]> git.alsa-project.org Git - alsa-lib.git/commitdiff
New PCM model with fragment concept removal and two interrupt sources
authorAbramo Bagnara <abramo@alsa-project.org>
Mon, 15 Jan 2001 11:06:53 +0000 (11:06 +0000)
committerAbramo Bagnara <abramo@alsa-project.org>
Mon, 15 Jan 2001 11:06:53 +0000 (11:06 +0000)
Renamed size_t/ssize_t to snd_pcm_sframes_t/snd_pcm_uframes_t

29 files changed:
TODO
include/pcm.h
src/pcm/interval.c
src/pcm/interval.h
src/pcm/interval_inline.h
src/pcm/mask.h
src/pcm/mask_inline.h
src/pcm/pcm.c
src/pcm/pcm_adpcm.c
src/pcm/pcm_alaw.c
src/pcm/pcm_copy.c
src/pcm/pcm_file.c
src/pcm/pcm_hw.c
src/pcm/pcm_linear.c
src/pcm/pcm_local.h
src/pcm/pcm_misc.c
src/pcm/pcm_mmap.c
src/pcm/pcm_mulaw.c
src/pcm/pcm_multi.c
src/pcm/pcm_null.c
src/pcm/pcm_params.c
src/pcm/pcm_plug.c
src/pcm/pcm_plugin.c
src/pcm/pcm_plugin.h
src/pcm/pcm_rate.c
src/pcm/pcm_route.c
src/pcm/pcm_share.c
src/pcm/pcm_shm.c
src/rawmidi/rawmidi_hw.c

diff --git a/TODO b/TODO
index d89b590999cac64d5835ddc4d7796dd3066984f8..cb99d9e93b0c9b5e9bd4dd77fe13d97548cc3bd2 100644 (file)
--- a/TODO
+++ b/TODO
@@ -1,3 +1,4 @@
+H change functions that take a FILE* to take a char * and a maximum size
 M think about xrun recovery helpers
 M add abstraction layer to timer, hwdep
 L move OSS emulation to user space? (pseudo device driver and daemon)
index 9e38827baa1ebc3fc2dc8022c775be97fd9ce94d..cd138ba5ff0b6f73d4c2384e3778de9d4c1e2a17 100644 (file)
@@ -47,8 +47,8 @@ int snd_pcm_open(snd_pcm_t **pcm, char *name,
 /* Obsolete functions */
 #define snd_pcm_write snd_pcm_writei
 #define snd_pcm_read snd_pcm_readi
-ssize_t snd_pcm_writev(snd_pcm_t *pcm, const struct iovec *vector, int count);
-ssize_t snd_pcm_readv(snd_pcm_t *pcm, const struct iovec *vector, int count);
+snd_pcm_sframes_t snd_pcm_writev(snd_pcm_t *pcm, const struct iovec *vector, int count);
+snd_pcm_sframes_t snd_pcm_readv(snd_pcm_t *pcm, const struct iovec *vector, int count);
 
 
 snd_pcm_type_t snd_pcm_type(snd_pcm_t *pcm);
@@ -69,12 +69,12 @@ int snd_pcm_drop(snd_pcm_t *pcm);
 int snd_pcm_drain(snd_pcm_t *pcm);
 int snd_pcm_pause(snd_pcm_t *pcm, int enable);
 int snd_pcm_state(snd_pcm_t *pcm);
-int snd_pcm_delay(snd_pcm_t *pcm, ssize_t *delayp);
-ssize_t snd_pcm_rewind(snd_pcm_t *pcm, size_t frames);
-ssize_t snd_pcm_writei(snd_pcm_t *pcm, const void *buffer, size_t size);
-ssize_t snd_pcm_readi(snd_pcm_t *pcm, void *buffer, size_t size);
-ssize_t snd_pcm_writen(snd_pcm_t *pcm, void **bufs, size_t size);
-ssize_t snd_pcm_readn(snd_pcm_t *pcm, void **bufs, size_t size);
+int snd_pcm_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp);
+snd_pcm_sframes_t snd_pcm_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
+snd_pcm_sframes_t snd_pcm_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size);
+snd_pcm_sframes_t snd_pcm_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size);
+snd_pcm_sframes_t snd_pcm_writen(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size);
+snd_pcm_sframes_t snd_pcm_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size);
 
 int snd_pcm_dump_hw_setup(snd_pcm_t *pcm, FILE *fp);
 int snd_pcm_dump_sw_setup(snd_pcm_t *pcm, FILE *fp);
@@ -85,13 +85,13 @@ int snd_pcm_link(snd_pcm_t *pcm1, snd_pcm_t *pcm2);
 int snd_pcm_unlink(snd_pcm_t *pcm);
 
 int snd_pcm_wait(snd_pcm_t *pcm, int timeout);
-ssize_t snd_pcm_avail_update(snd_pcm_t *pcm);
-int snd_pcm_set_avail_min(snd_pcm_t *pcm, size_t size);
+snd_pcm_sframes_t snd_pcm_avail_update(snd_pcm_t *pcm);
+int snd_pcm_set_avail_min(snd_pcm_t *pcm, snd_pcm_uframes_t size);
 
 typedef struct _mask mask_t;
 size_t mask_sizeof();
 void mask_none(mask_t *mask);
-void mask_all(mask_t *mask);
+void mask_any(mask_t *mask);
 void mask_load(mask_t *mask, unsigned int msk);
 int mask_empty(const mask_t *mask);
 void mask_set(mask_t *mask, unsigned int val);
@@ -99,48 +99,59 @@ void mask_reset(mask_t *mask, unsigned int val);
 void mask_copy(mask_t *mask, const mask_t *v);
 int mask_test(const mask_t *mask, unsigned int val);
 void mask_intersect(mask_t *mask, const mask_t *v);
+void mask_union(mask_t *mask, const mask_t *v);
 int mask_eq(const mask_t *a, const mask_t *b);
 int mask_single(const mask_t *mask);
 
 int snd_pcm_hw_params_any(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
 int snd_pcm_hw_param_any(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
-                        unsigned int var);
+                        snd_pcm_hw_param_t var);
+int snd_pcm_hw_param_setinteger(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
+                               snd_pcm_hw_param_t var);
 int snd_pcm_hw_param_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
-                           unsigned int par);
+                          snd_pcm_hw_param_t var, int *dir);
 int snd_pcm_hw_param_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
-                          unsigned int par);
+                         snd_pcm_hw_param_t var, int *dir);
 int snd_pcm_hw_param_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
-                          unsigned int var, unsigned int val);
+                         snd_pcm_hw_param_t var, unsigned int val,
+                         int *dir);
 int snd_pcm_hw_param_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
-                         unsigned int var, unsigned int val);
+                        snd_pcm_hw_param_t var,
+                        unsigned int val, int *dir);
 int snd_pcm_hw_param_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
-                         unsigned int var, unsigned int val);
+                        snd_pcm_hw_param_t var, unsigned int val, int *dir);
 int snd_pcm_hw_param_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
-                            unsigned int var, unsigned int min, unsigned int max);
+                           snd_pcm_hw_param_t var,
+                           unsigned int *min, int *mindir,
+                           unsigned int *max, int *maxdir);
 int snd_pcm_hw_param_set(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
-                         unsigned int var, unsigned int val);
+                        snd_pcm_hw_param_t var, unsigned int val, int dir);
 int snd_pcm_hw_param_mask(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
-                          unsigned int var, const mask_t *mask);
+                         snd_pcm_hw_param_t var, const mask_t *mask);
 int snd_pcm_hw_param_min_try(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
-                            unsigned int var, unsigned int val);
+                            snd_pcm_hw_param_t var, 
+                            unsigned int val, int *dir);
 int snd_pcm_hw_param_max_try(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
-                            unsigned int var, unsigned int val);
+                            snd_pcm_hw_param_t var,
+                            unsigned int val, int *dir);
 int snd_pcm_hw_param_minmax_try(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
-                               unsigned int var, unsigned int min, unsigned int max);
+                               snd_pcm_hw_param_t var,
+                               unsigned int *min, int *mindir,
+                               unsigned int *max, int *maxdir);
 int snd_pcm_hw_param_set_try(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
-                            unsigned int var, unsigned int val);
+                            snd_pcm_hw_param_t var, unsigned int val, int dir);
 int snd_pcm_hw_param_mask_try(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
-                             unsigned int var, const mask_t *mask);
+                             snd_pcm_hw_param_t var, const mask_t *mask);
 int snd_pcm_hw_param_value(const snd_pcm_hw_params_t *params,
-                          unsigned int var);
+                          snd_pcm_hw_param_t var, int *dir);
 const mask_t *snd_pcm_hw_param_value_mask(const snd_pcm_hw_params_t *params,
-                                         unsigned int var);
+                                         snd_pcm_hw_param_t var);
 const interval_t *snd_pcm_hw_param_value_interval(const snd_pcm_hw_params_t *params,
-                                                 unsigned int var);
+                                                 snd_pcm_hw_param_t var);
 unsigned int snd_pcm_hw_param_value_min(const snd_pcm_hw_params_t *params,
-                                       unsigned int var);
+                                       snd_pcm_hw_param_t var, int *dir);
 unsigned int snd_pcm_hw_param_value_max(const snd_pcm_hw_params_t *params,
-                                       unsigned int var);
+                                       snd_pcm_hw_param_t var, int *dir);
 int snd_pcm_hw_params_try_explain_failure(snd_pcm_t *pcm,
                                          snd_pcm_hw_params_t *fail,
                                          snd_pcm_hw_params_t *success,
@@ -174,73 +185,73 @@ int snd_pcm_hw_strategy_simple(snd_pcm_hw_strategy_t **strategyp,
                               unsigned int badness_min,
                               unsigned int badness_max);
 int snd_pcm_hw_strategy_simple_near(snd_pcm_hw_strategy_t *strategy, int order,
-                                   unsigned int param,
+                                   snd_pcm_hw_param_t var,
                                    unsigned int best,
                                    unsigned int mul);
 int snd_pcm_hw_strategy_simple_choices(snd_pcm_hw_strategy_t *strategy, int order,
-                                      unsigned int param,
+                                      snd_pcm_hw_param_t var,
                                       unsigned int count,
                                       snd_pcm_hw_strategy_simple_choices_list_t *choices);
 
-#define SND_PCM_SW_PARAM_START_MODE            0
-#define SND_PCM_SW_PARAM_READY_MODE            1
-#define SND_PCM_SW_PARAM_XRUN_MODE             2
-#define SND_PCM_SW_PARAM_SILENCE_MODE          3
-#define SND_PCM_SW_PARAM_TSTAMP_MODE           4
-#define SND_PCM_SW_PARAM_AVAIL_MIN             5
-#define SND_PCM_SW_PARAM_XFER_ALIGN            6
-#define SND_PCM_SW_PARAM_SILENCE_THRESHOLD     7
-#define SND_PCM_SW_PARAM_SILENCE_SIZE          8
-#define SND_PCM_SW_PARAM_LAST                  8
+typedef enum _snd_pcm_sw_param {
+       SND_PCM_SW_PARAM_START_MODE,
+       SND_PCM_SW_PARAM_XRUN_MODE,
+       SND_PCM_SW_PARAM_TSTAMP_MODE,
+       SND_PCM_SW_PARAM_PERIOD_STEP,
+       SND_PCM_SW_PARAM_SLEEP_MIN,
+       SND_PCM_SW_PARAM_AVAIL_MIN,
+       SND_PCM_SW_PARAM_XFER_ALIGN,
+       SND_PCM_SW_PARAM_SILENCE_THRESHOLD,
+       SND_PCM_SW_PARAM_SILENCE_SIZE,
+       SND_PCM_SW_PARAM_LAST = SND_PCM_SW_PARAM_SILENCE_SIZE,
+} snd_pcm_sw_param_t;
 
 int snd_pcm_sw_params_current(snd_pcm_t *pcm, snd_pcm_sw_params_t *params);
-int snd_pcm_sw_param_set(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, unsigned int var, unsigned int val);
-int snd_pcm_sw_param_near(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, unsigned int var, unsigned int val);
-int snd_pcm_sw_param_value(snd_pcm_sw_params_t *params, unsigned int var);
+int snd_pcm_sw_param_set(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_sw_param_t var, unsigned int val);
+int snd_pcm_sw_param_near(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_sw_param_t var, unsigned int val);
+int snd_pcm_sw_param_value(snd_pcm_sw_params_t *params, snd_pcm_sw_param_t var);
 int snd_pcm_sw_params_dump(snd_pcm_sw_params_t *params, FILE *fp);
 
 /* mmap */
 const snd_pcm_channel_area_t *snd_pcm_mmap_areas(snd_pcm_t *pcm);
 const snd_pcm_channel_area_t *snd_pcm_mmap_running_areas(snd_pcm_t *pcm);
 const snd_pcm_channel_area_t *snd_pcm_mmap_stopped_areas(snd_pcm_t *pcm);
-ssize_t snd_pcm_mmap_forward(snd_pcm_t *pcm, size_t size);
-size_t snd_pcm_mmap_offset(snd_pcm_t *pcm);
-size_t snd_pcm_mmap_xfer(snd_pcm_t *pcm, size_t size);
-ssize_t snd_pcm_mmap_writei(snd_pcm_t *pcm, const void *buffer, size_t size);
-ssize_t snd_pcm_mmap_readi(snd_pcm_t *pcm, void *buffer, size_t size);
-ssize_t snd_pcm_mmap_writen(snd_pcm_t *pcm, void **bufs, size_t size);
-ssize_t snd_pcm_mmap_readn(snd_pcm_t *pcm, void **bufs, size_t size);
+snd_pcm_sframes_t snd_pcm_mmap_forward(snd_pcm_t *pcm, snd_pcm_uframes_t size);
+snd_pcm_uframes_t snd_pcm_mmap_offset(snd_pcm_t *pcm);
+snd_pcm_uframes_t snd_pcm_mmap_xfer(snd_pcm_t *pcm, snd_pcm_uframes_t size);
+snd_pcm_sframes_t snd_pcm_mmap_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size);
+snd_pcm_sframes_t snd_pcm_mmap_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size);
+snd_pcm_sframes_t snd_pcm_mmap_writen(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size);
+snd_pcm_sframes_t snd_pcm_mmap_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size);
 
-const char *snd_pcm_stream_name(unsigned int stream);
-const char *snd_pcm_hw_param_name(unsigned int params);
-const char *snd_pcm_sw_param_name(unsigned int params);
-const char *snd_pcm_access_name(unsigned int access);
-const char *snd_pcm_format_name(unsigned int format);
-const char *snd_pcm_subformat_name(unsigned int subformat);
-const char *snd_pcm_format_description(unsigned int format);
+const char *snd_pcm_stream_name(snd_pcm_stream_t stream);
+const char *snd_pcm_hw_param_name(snd_pcm_hw_param_t var);
+const char *snd_pcm_sw_param_name(snd_pcm_sw_param_t var);
+const char *snd_pcm_access_name(snd_pcm_access_t access);
+const char *snd_pcm_format_name(snd_pcm_format_t format);
+const char *snd_pcm_subformat_name(snd_pcm_subformat_t subformat);
+const char *snd_pcm_format_description(snd_pcm_format_t format);
 int snd_pcm_format_value(const char* name);
-const char *snd_pcm_start_mode_name(unsigned int mode);
-const char *snd_pcm_ready_mode_name(unsigned int mode);
-const char *snd_pcm_xrun_mode_name(unsigned int mode);
-const char *snd_pcm_silence_mode_name(unsigned int mode);
-const char *snd_pcm_tstamp_mode_name(unsigned int mode);
-const char *snd_pcm_state_name(unsigned int state);
+const char *snd_pcm_start_mode_name(snd_pcm_start_t mode);
+const char *snd_pcm_xrun_mode_name(snd_pcm_xrun_t mode);
+const char *snd_pcm_tstamp_mode_name(snd_pcm_tstamp_t mode);
+const char *snd_pcm_state_name(snd_pcm_state_t state);
 
-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,
-                         size_t vcount, size_t frames, int format);
-int snd_pcm_area_copy(const snd_pcm_channel_area_t *src_channel, size_t src_offset,
-                     const snd_pcm_channel_area_t *dst_channel, size_t dst_offset,
-                     size_t samples, int format);
-int snd_pcm_areas_copy(const snd_pcm_channel_area_t *src_channels, size_t src_offset,
-                      const snd_pcm_channel_area_t *dst_channels, size_t dst_offset,
-                      size_t channels, size_t frames, int format);
+int snd_pcm_area_silence(const snd_pcm_channel_area_t *dst_channel, snd_pcm_uframes_t dst_offset,
+                        unsigned int samples, int format);
+int snd_pcm_areas_silence(const snd_pcm_channel_area_t *dst_channels, snd_pcm_uframes_t dst_offset,
+                         unsigned int channels, snd_pcm_uframes_t frames, int format);
+int snd_pcm_area_copy(const snd_pcm_channel_area_t *src_channel, snd_pcm_uframes_t src_offset,
+                     const snd_pcm_channel_area_t *dst_channel, snd_pcm_uframes_t dst_offset,
+                     unsigned int samples, int format);
+int snd_pcm_areas_copy(const snd_pcm_channel_area_t *src_channels, snd_pcm_uframes_t src_offset,
+                      const snd_pcm_channel_area_t *dst_channels, snd_pcm_uframes_t dst_offset,
+                      unsigned int channels, snd_pcm_uframes_t frames, int format);
 
-ssize_t snd_pcm_bytes_to_frames(snd_pcm_t *pcm, ssize_t bytes);
-ssize_t snd_pcm_frames_to_bytes(snd_pcm_t *pcm, ssize_t frames);
-ssize_t snd_pcm_bytes_to_samples(snd_pcm_t *pcm, ssize_t bytes);
-ssize_t snd_pcm_samples_to_bytes(snd_pcm_t *pcm, ssize_t samples);
+snd_pcm_sframes_t snd_pcm_bytes_to_frames(snd_pcm_t *pcm, ssize_t bytes);
+ssize_t snd_pcm_frames_to_bytes(snd_pcm_t *pcm, snd_pcm_sframes_t frames);
+int snd_pcm_bytes_to_samples(snd_pcm_t *pcm, ssize_t bytes);
+ssize_t snd_pcm_samples_to_bytes(snd_pcm_t *pcm, int samples);
 
 
 /* misc */
@@ -259,7 +270,7 @@ 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);
 u_int64_t snd_pcm_format_silence_64(int format);
-ssize_t snd_pcm_format_set_silence(int format, void *buf, size_t count);
+int snd_pcm_format_set_silence(int format, void *buf, unsigned int samples);
 
 #ifdef __cplusplus
 }
index 2a5283d9dc1ebeca8bdcb253ec237722bfd56905..0e2793b9e9e49c8094188aa844bf7dc8b4a77fe1 100644 (file)
@@ -58,6 +58,8 @@ static inline unsigned int div_up(unsigned int a, unsigned int b)
 
 static inline unsigned int mul(unsigned int a, unsigned int b)
 {
+       if (a == 0)
+               return 0;
        if (div_down(UINT_MAX, a) < b)
                return UINT_MAX;
        return a * b;
@@ -89,10 +91,9 @@ static inline unsigned int muldiv32(unsigned int a, unsigned int b,
        return n;
 }
 
-int interval_refine_min(interval_t *i, unsigned int min)
+int interval_refine_min(interval_t *i, unsigned int min, int openmin)
 {
        int changed = 0;
-       int openmin = 0;
        assert(!interval_empty(i));
        if (i->min < min) {
                i->min = min;
@@ -102,24 +103,22 @@ int interval_refine_min(interval_t *i, unsigned int min)
                i->openmin = 1;
                changed = 1;
        }
-       if (!i->real) {
+       if (i->integer) {
                if (i->openmin) {
                        i->min++;
                        i->openmin = 0;
                }
        }
        if (interval_checkempty(i)) {
-               i->empty = 1;
+               interval_none(i);
                return -EINVAL;
        }
        return changed;
 }
 
-int interval_refine_max(interval_t *i, unsigned int max)
+int interval_refine_max(interval_t *i, unsigned int max, int openmax)
 {
        int changed = 0;
-       int openmax = 1;
-       max = add(max, 1);
        assert(!interval_empty(i));
        if (i->max > max) {
                i->max = max;
@@ -129,14 +128,14 @@ int interval_refine_max(interval_t *i, unsigned int max)
                i->openmax = 1;
                changed = 1;
        }
-       if (!i->real) {
+       if (i->integer) {
                if (i->openmax) {
                        i->max--;
                        i->openmax = 0;
                }
        }
        if (interval_checkempty(i)) {
-               i->empty = 1;
+               interval_none(i);
                return -EINVAL;
        }
        return changed;
@@ -163,7 +162,11 @@ int interval_refine(interval_t *i, const interval_t *v)
                i->openmax = 1;
                changed = 1;
        }
-       if (!i->real) {
+       if (!i->integer && v->integer) {
+               i->integer = 1;
+               changed = 1;
+       }
+       if (i->integer) {
                if (i->openmin) {
                        i->min++;
                        i->openmin = 0;
@@ -172,9 +175,10 @@ int interval_refine(interval_t *i, const interval_t *v)
                        i->max--;
                        i->openmax = 0;
                }
-       }
+       } else if (!i->openmin && !i->openmax && i->min == i->max)
+               i->integer = 1;
        if (interval_checkempty(i)) {
-               i->empty = 1;
+               interval_none(i);
                return -EINVAL;
        }
        return changed;
@@ -183,8 +187,7 @@ int interval_refine(interval_t *i, const interval_t *v)
 int interval_refine_first(interval_t *i)
 {
        assert(!interval_empty(i));
-       if (i->min == i->max ||
-               (i->min + 1 == i->max && i->openmin && i->openmax))
+       if (interval_single(i))
                return 0;
        i->max = i->min;
        i->openmax = i->openmin;
@@ -196,8 +199,7 @@ int interval_refine_first(interval_t *i)
 int interval_refine_last(interval_t *i)
 {
        assert(!interval_empty(i));
-       if (i->min == i->max ||
-               (i->min + 1 == i->max && i->openmin && i->openmax))
+       if (interval_single(i))
                return 0;
        i->min = i->max;
        i->openmin = i->openmax;
@@ -209,107 +211,154 @@ int interval_refine_last(interval_t *i)
 int interval_refine_set(interval_t *i, unsigned int val)
 {
        interval_t t;
-       t.min = val;
-       t.openmin = 0;
-       t.max = add(val, 1);
-       t.openmax = 1;
+       t.empty = 0;
+       t.min = t.max = val;
+       t.openmin = t.openmax = 0;
+       t.integer = 1;
        return interval_refine(i, &t);
 }
 
-/* a <- b + c */
-int interval_add(interval_t *a, const interval_t *b, const interval_t *c)
+void interval_add(const interval_t *a, const interval_t *b, interval_t *c)
 {
-       interval_t t;
-       assert(!a->empty && !b->empty && !c->empty);
-       t.min = add(b->min, c->min);
-       t.openmin = (b->openmin || c->openmin);
-       t.max = add(b->max,  c->max);
-       t.openmax = (b->openmax || c->openmax);
-       return interval_refine(a, &t);
+       if (a->empty || b->empty) {
+               interval_none(c);
+               return;
+       }
+       c->empty = 0;
+       c->min = add(a->min, b->min);
+       c->openmin = (a->openmin || b->openmin);
+       c->max = add(a->max,  b->max);
+       c->openmax = (a->openmax || b->openmax);
+       c->integer = (a->integer && b->integer);
 }
 
-/* a <- b - c */
-int interval_sub(interval_t *a, const interval_t *b, const interval_t *c)
+void interval_sub(const interval_t *a, const interval_t *b, interval_t *c)
 {
-       interval_t t;
-       assert(!a->empty && !b->empty && !c->empty);
-       t.min = sub(b->min, c->max);
-       t.openmin = (b->openmin || c->openmax);
-       t.max = add(b->max,  c->min);
-       t.openmax = (b->openmax || c->openmin);
-       return interval_refine(a, &t);
+       if (a->empty || b->empty) {
+               interval_none(c);
+               return;
+       }
+       c->empty = 0;
+       c->min = sub(a->min, b->max);
+       c->openmin = (a->openmin || b->openmax);
+       c->max = add(a->max,  b->min);
+       c->openmax = (a->openmax || b->openmin);
+       c->integer = (a->integer && b->integer);
 }
 
-/* a <- b * c */
-int interval_mul(interval_t *a, const interval_t *b, const interval_t *c)
+void interval_mul(const interval_t *a, const interval_t *b, interval_t *c)
 {
-       interval_t t;
-       assert(!a->empty && !b->empty && !c->empty);
-       t.min = mul(b->min, c->min);
-       t.openmin = (b->openmin || c->openmin);
-       t.max = mul(b->max,  c->max);
-       t.openmax = (b->openmax || c->openmax);
-       return interval_refine(a, &t);
+       if (a->empty || b->empty) {
+               interval_none(c);
+               return;
+       }
+       c->empty = 0;
+       c->min = mul(a->min, b->min);
+       c->openmin = (a->openmin || b->openmin);
+       c->max = mul(a->max,  b->max);
+       c->openmax = (a->openmax || b->openmax);
+       c->integer = (a->integer && b->integer);
 }
 
-/* a <- b / c */
-int interval_div(interval_t *a, const interval_t *b, const interval_t *c)
+void interval_div(const interval_t *a, const interval_t *b, interval_t *c)
 {
-       interval_t t;
        unsigned int r;
-       assert(!a->empty && !b->empty && !c->empty);
-       t.min = div32(b->min, c->max, &r);
-       t.openmin = (r || b->openmin || c->openmax);
-       t.max = div32(b->max, c->min, &r);
-       if (r) {
-               t.max++;
-               t.openmax = 1;
-       } else
-               t.openmax = (b->openmax || c->openmin);
-       return interval_refine(a, &t);
+       if (a->empty || b->empty) {
+               interval_none(c);
+               return;
+       }
+       c->empty = 0;
+       c->min = div32(a->min, b->max, &r);
+       c->openmin = (r || a->openmin || b->openmax);
+       if (b->min > 0) {
+               c->max = div32(a->max, b->min, &r);
+               if (r) {
+                       c->max++;
+                       c->openmax = 1;
+               } else
+                       c->openmax = (a->openmax || b->openmin);
+       } else {
+               c->max = UINT_MAX;
+               c->openmax = 0;
+       }
+       c->integer = 0;
 }
 
-
-/* a <- b * c / k */
-int interval_muldivk(interval_t *a, unsigned int k,
-                   const interval_t *b, const interval_t *c)
+/* a * b / c */
+void interval_muldiv(const interval_t *a, const interval_t *b,
+                    const interval_t *c, interval_t *d)
 {
-       interval_t t;
        unsigned int r;
-       assert(!a->empty && !b->empty && !c->empty);
-       t.min = muldiv32(b->min, c->min, k, &r);
-       t.openmin = (r || b->openmin || c->openmin);
-       t.max = muldiv32(b->max, c->max, k, &r);
+       if (a->empty || b->empty || c->empty) {
+               interval_none(d);
+               return;
+       }
+       d->empty = 0;
+       d->min = muldiv32(a->min, b->min, c->max, &r);
+       d->openmin = (r || a->openmin || b->openmin || c->openmax);
+       d->max = muldiv32(a->max, b->max, c->min, &r);
        if (r) {
-               t.max++;
-               t.openmax = 1;
+               d->max++;
+               d->openmax = 1;
        } else
-               t.openmax = (b->openmax || c->openmax);
-       return interval_refine(a, &t);
+               d->openmax = (a->openmax || b->openmax || c->openmin);
+       d->integer = 0;
 }
 
-/* a <- b * k / c */
-int interval_mulkdiv(interval_t *a, unsigned int k,
-                    const interval_t *b, const interval_t *c)
+/* a * b / k */
+void interval_muldivk(const interval_t *a, const interval_t *b,
+                     unsigned int k, interval_t *c)
 {
-       interval_t t;
        unsigned int r;
-       assert(!a->empty && !b->empty && !c->empty);
-       t.min = muldiv32(b->min, k, c->max, &r);
-       t.openmin = (r || b->openmin || c->openmax);
-       t.max = muldiv32(b->max, k, c->min, &r);
+       if (a->empty || b->empty) {
+               interval_none(c);
+               return;
+       }
+       c->empty = 0;
+       c->min = muldiv32(a->min, b->min, k, &r);
+       c->openmin = (r || a->openmin || b->openmin);
+       c->max = muldiv32(a->max, b->max, k, &r);
        if (r) {
-               t.max++;
-               t.openmax = 1;
+               c->max++;
+               c->openmax = 1;
        } else
-               t.openmax = (b->openmax || c->openmin);
-       return interval_refine(a, &t);
+               c->openmax = (a->openmax || b->openmax);
+       c->integer = 0;
+}
+
+/* a * k / b */
+void interval_mulkdiv(const interval_t *a, unsigned int k,
+                     const interval_t *b, interval_t *c)
+{
+       unsigned int r;
+       if (a->empty || b->empty) {
+               interval_none(c);
+               return;
+       }
+       c->empty = 0;
+       c->min = muldiv32(a->min, k, b->max, &r);
+       c->openmin = (r || a->openmin || b->openmax);
+       if (b->min > 0) {
+               c->max = muldiv32(a->max, k, b->min, &r);
+               if (r) {
+                       c->max++;
+                       c->openmax = 1;
+               } else
+                       c->openmax = (a->openmax || b->openmin);
+       } else {
+               c->max = UINT_MAX;
+               c->openmax = 0;
+       }
+       c->integer = 0;
 }
 
 void interval_print(const interval_t *i, FILE *fp)
 {
        if (interval_empty(i))
                fprintf(fp, "NONE");
+       else if (i->min == 0 && i->openmin == 0 && 
+                i->max == UINT_MAX && i->openmax == 0)
+               fprintf(fp, "ALL");
        else if (interval_single(i))
                fprintf(fp, "%u", interval_value(i));
        else
index 8c6e0d8dcce6ebd1f0f5522f44bdfc4945faea3b..2f549b42e4c584facd68e7ab32ea98ee71befbec 100644 (file)
@@ -24,8 +24,9 @@
 #ifdef INTERVAL_INLINE
 #include "interval_inline.h"
 #else
-void interval_all(interval_t *i);
-void interval_setreal(interval_t *i);
+void interval_any(interval_t *i);
+void interval_none(interval_t *i);
+int interval_setinteger(interval_t *i);
 int interval_empty(const interval_t *i);
 int interval_single(const interval_t *i);
 int interval_value(const interval_t *i);
@@ -33,20 +34,24 @@ int interval_min(const interval_t *i);
 int interval_max(const interval_t *i);
 int interval_test(const interval_t *i, unsigned int val);
 void interval_copy(interval_t *dst, const interval_t *src);
-int interval_eq(const interval_t *i1, const interval_t *i2);
+void interval_round(interval_t *i);
+int interval_always_eq(const interval_t *i1, const interval_t *i2);
+int interval_never_eq(const interval_t *i1, const interval_t *i2);
 #endif
 
-int interval_add(interval_t *a, const interval_t *b, const interval_t *c);
-int interval_sub(interval_t *a, const interval_t *b, const interval_t *c);
-int interval_mul(interval_t *a, const interval_t *b, const interval_t *c);
-int interval_div(interval_t *a, const interval_t *b, const interval_t *c);
-int interval_muldivk(interval_t *a, unsigned int k,
-                    const interval_t *b, const interval_t *c);
-int interval_mulkdiv(interval_t *a, unsigned int k,
-                    const interval_t *b, const interval_t *c);
+void interval_add(const interval_t *a, const interval_t *b, interval_t *c);
+void interval_sub(const interval_t *a, const interval_t *b, interval_t *c);
+void interval_mul(const interval_t *a, const interval_t *b, interval_t *c);
+void interval_div(const interval_t *a, const interval_t *b, interval_t *c);
+void interval_muldiv(const interval_t *a, const interval_t *b, 
+                    const interval_t *c, interval_t *d);
+void interval_muldivk(const interval_t *a, const interval_t *b, 
+                     unsigned int k, interval_t *c);
+void interval_mulkdiv(const interval_t *a, unsigned int k,
+                     const interval_t *b, interval_t *c);
 void interval_print(const interval_t *i, FILE *fp);
-int interval_refine_min(interval_t *i, unsigned int min);
-int interval_refine_max(interval_t *i, unsigned int max);
+int interval_refine_min(interval_t *i, unsigned int min, int openmin);
+int interval_refine_max(interval_t *i, unsigned int max, int openmax);
 int interval_refine(interval_t *i, const interval_t *v);
 int interval_refine_first(interval_t *i);
 int interval_refine_last(interval_t *i);
index ae78bcf6c509df35d7b53a4a56a3afaa965d225c..a14c83eb940f56a20f9c656a6e47f604d4b518e6 100644 (file)
 #define INLINE extern inline
 #endif
 
-INLINE void interval_all(interval_t *i)
+INLINE void interval_any(interval_t *i)
 {
-       i->min = 1;
+       i->min = 0;
+       i->openmin = 0;
        i->max = UINT_MAX;
+       i->openmax = 0;
+       i->integer = 0;
+       i->empty = 0;
+}
+
+INLINE void interval_none(interval_t *i)
+{
+       i->empty = 1;
 }
 
 INLINE int interval_checkempty(const interval_t *i)
@@ -63,12 +72,8 @@ INLINE int interval_min(const interval_t *i)
 
 INLINE int interval_max(const interval_t *i)
 {
-       unsigned int v;
        assert(!interval_empty(i));
-       v = i->max;
-       if (i->openmax)
-               v--;
-       return v;
+       return i->max;
 }
 
 INLINE int interval_test(const interval_t *i, unsigned int val)
@@ -82,18 +87,42 @@ INLINE void interval_copy(interval_t *d, const interval_t *s)
        *d = *s;
 }
 
-INLINE void interval_setreal(interval_t *i)
+INLINE int interval_setinteger(interval_t *i)
+{
+       if (i->integer)
+               return 0;
+       if (i->openmin && i->openmax && i->min == i->max)
+               return -EINVAL;
+       i->integer = 1;
+       return 1;
+}
+
+INLINE void interval_round(interval_t *i)
 {
-       i->real = 1;
+       assert(!interval_empty(i));
+       if (i->integer)
+               return;
+       i->openmin = 0;
+       i->openmax = 0;
+       i->integer = 1;
+}
+
+INLINE int interval_always_eq(const interval_t *i1, const interval_t *i2)
+{
+       return interval_single(i1) && interval_single(i2) &&
+               interval_value(i1) == interval_value(i2);
 }
 
-INLINE int interval_eq(const interval_t *i1, const interval_t *i2)
+INLINE int interval_never_eq(const interval_t *i1, const interval_t *i2)
 {
-       if (i1->empty)
-               return i2->empty;
-       if (i2->empty)
-               return i1->empty;
-       return i1->min == i2->min && i1->openmin == i2->openmin &&
-               i1->max == i2->max && i1->openmax == i2->openmax;
+       
+       return (i1->max < i2->min || 
+               (i1->max == i2->min &&
+                (i1->openmax || i1->openmin)) ||
+               i1->min > i2->max ||
+               (i1->min == i2->max &&
+                (i1->openmin || i2->openmax)));
 }
 
+
+
index 8a65461900f3522c9dd82a8a0ce52f4f51cf3f64..b6e6792c6afac344ca36bd4280748b343fe2e7ba 100644 (file)
@@ -31,7 +31,7 @@
 #include "mask_inline.h"
 #else
 void mask_none(mask_t *mask);
-void mask_all(mask_t *mask);
+void mask_any(mask_t *mask);
 void mask_load(mask_t *mask, unsigned int msk);
 int mask_empty(const mask_t *mask);
 int mask_full(const mask_t *mask);
@@ -40,6 +40,7 @@ void mask_reset(mask_t *mask, unsigned int val);
 void mask_copy(mask_t *mask, const mask_t *v);
 int mask_test(const mask_t *mask, unsigned int val);
 void mask_intersect(mask_t *mask, const mask_t *v);
+void mask_union(mask_t *mask, const mask_t *v);
 unsigned int mask_count(const mask_t *mask);
 unsigned int mask_min(const mask_t *mask);
 unsigned int mask_max(const mask_t *mask);
@@ -55,4 +56,6 @@ int mask_refine_min(mask_t *mask, unsigned int val);
 int mask_refine_max(mask_t *mask, unsigned int val);
 int mask_refine_set(mask_t *mask, unsigned int val);
 int mask_value(const mask_t *mask);
+int mask_always_eq(const mask_t *m1, const mask_t *m2);
+int mask_never_eq(const mask_t *m1, const mask_t *m2);
 #endif
index 448921106ac7e2ac1c3566e172c3395a4522b726..5f3e1a1ad0456e9350f3698cde5fe486c3ed2bd1 100644 (file)
@@ -82,7 +82,7 @@ INLINE void mask_none(mask_t *mask)
        mask_bits(mask) = 0;
 }
 
-INLINE void mask_all(mask_t *mask)
+INLINE void mask_any(mask_t *mask)
 {
        mask_bits(mask) = ~0U;
 }
@@ -154,6 +154,11 @@ INLINE void mask_intersect(mask_t *mask, const mask_t *v)
        mask_bits(mask) &= mask_bits(v);
 }
 
+INLINE void mask_union(mask_t *mask, const mask_t *v)
+{
+       mask_bits(mask) |= mask_bits(v);
+}
+
 INLINE int mask_eq(const mask_t *mask, const mask_t *v)
 {
        return mask_bits(mask) == mask_bits(v);
@@ -243,3 +248,14 @@ INLINE int mask_value(const mask_t *mask)
        assert(!mask_empty(mask));
        return mask_min(mask);
 }
+
+INLINE int mask_always_eq(const mask_t *m1, const mask_t *m2)
+{
+       return mask_single(m1) && mask_single(m2) &&
+               mask_value(m1) == mask_value(m2);
+}
+
+INLINE int mask_never_eq(const mask_t *m1, const mask_t *m2)
+{
+       return (mask_bits(m1) & mask_bits(m2)) == 0;
+}
index b94d3208c7290673a0b6666c98852bdcec0e20c1..2cbce95e46037edd2b15908394b34346f67ef3f5 100644 (file)
@@ -106,7 +106,7 @@ int snd_pcm_state(snd_pcm_t *pcm)
        return pcm->fast_ops->state(pcm->fast_op_arg);
 }
 
-int snd_pcm_delay(snd_pcm_t *pcm, ssize_t *delayp)
+int snd_pcm_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp)
 {
        assert(pcm);
        assert(pcm->setup);
@@ -156,7 +156,7 @@ int snd_pcm_pause(snd_pcm_t *pcm, int enable)
 }
 
 
-ssize_t snd_pcm_rewind(snd_pcm_t *pcm, size_t frames)
+snd_pcm_sframes_t snd_pcm_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
 {
        assert(pcm);
        assert(pcm->setup);
@@ -164,7 +164,7 @@ ssize_t snd_pcm_rewind(snd_pcm_t *pcm, size_t frames)
        return pcm->fast_ops->rewind(pcm->fast_op_arg, frames);
 }
 
-ssize_t snd_pcm_writei(snd_pcm_t *pcm, const void *buffer, size_t size)
+snd_pcm_sframes_t snd_pcm_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size)
 {
        assert(pcm);
        assert(size == 0 || buffer);
@@ -173,7 +173,7 @@ ssize_t snd_pcm_writei(snd_pcm_t *pcm, const void *buffer, size_t size)
        return _snd_pcm_writei(pcm, buffer, size);
 }
 
-ssize_t snd_pcm_writen(snd_pcm_t *pcm, void **bufs, size_t size)
+snd_pcm_sframes_t snd_pcm_writen(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size)
 {
        assert(pcm);
        assert(size == 0 || bufs);
@@ -182,7 +182,7 @@ ssize_t snd_pcm_writen(snd_pcm_t *pcm, void **bufs, size_t size)
        return _snd_pcm_writen(pcm, bufs, size);
 }
 
-ssize_t snd_pcm_readi(snd_pcm_t *pcm, void *buffer, size_t size)
+snd_pcm_sframes_t snd_pcm_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size)
 {
        assert(pcm);
        assert(size == 0 || buffer);
@@ -191,7 +191,7 @@ ssize_t snd_pcm_readi(snd_pcm_t *pcm, void *buffer, size_t size)
        return _snd_pcm_readi(pcm, buffer, size);
 }
 
-ssize_t snd_pcm_readn(snd_pcm_t *pcm, void **bufs, size_t size)
+snd_pcm_sframes_t snd_pcm_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size)
 {
        assert(pcm);
        assert(size == 0 || bufs);
@@ -200,7 +200,7 @@ ssize_t snd_pcm_readn(snd_pcm_t *pcm, void **bufs, size_t size)
        return _snd_pcm_readn(pcm, bufs, size);
 }
 
-ssize_t snd_pcm_writev(snd_pcm_t *pcm, const struct iovec *vector, int count)
+snd_pcm_sframes_t snd_pcm_writev(snd_pcm_t *pcm, const struct iovec *vector, int count)
 {
        void **bufs;
        int k;
@@ -215,7 +215,7 @@ ssize_t snd_pcm_writev(snd_pcm_t *pcm, const struct iovec *vector, int count)
        return snd_pcm_writen(pcm, bufs, vector[0].iov_len);
 }
 
-ssize_t snd_pcm_readv(snd_pcm_t *pcm, const struct iovec *vector, int count)
+snd_pcm_sframes_t snd_pcm_readv(snd_pcm_t *pcm, const struct iovec *vector, int count)
 {
        void **bufs;
        int k;
@@ -310,25 +310,26 @@ char *snd_pcm_hw_param_names[] = {
        HW_PARAM(ACCESS),
        HW_PARAM(FORMAT),
        HW_PARAM(SUBFORMAT),
+       HW_PARAM(SAMPLE_BITS),
+       HW_PARAM(FRAME_BITS),
        HW_PARAM(CHANNELS),
        HW_PARAM(RATE),
-       HW_PARAM(FRAGMENT_LENGTH),
-       HW_PARAM(FRAGMENT_SIZE),
-       HW_PARAM(FRAGMENTS),
-       HW_PARAM(BUFFER_LENGTH),
+       HW_PARAM(PERIOD_TIME),
+       HW_PARAM(PERIOD_SIZE),
+       HW_PARAM(PERIOD_BYTES),
+       HW_PARAM(PERIODS),
+       HW_PARAM(BUFFER_TIME),
        HW_PARAM(BUFFER_SIZE),
-       HW_PARAM(SAMPLE_BITS),
-       HW_PARAM(FRAME_BITS),
-       HW_PARAM(FRAGMENT_BYTES),
        HW_PARAM(BUFFER_BYTES),
+       HW_PARAM(TICK_TIME),
 };
 
 char *snd_pcm_sw_param_names[] = {
        SW_PARAM(START_MODE),
-       SW_PARAM(READY_MODE),
        SW_PARAM(XRUN_MODE),
-       SW_PARAM(SILENCE_MODE),
        SW_PARAM(TSTAMP_MODE),
+       SW_PARAM(PERIOD_STEP),
+       SW_PARAM(SLEEP_MIN),
        SW_PARAM(AVAIL_MIN),
        SW_PARAM(XFER_ALIGN),
        SW_PARAM(SILENCE_THRESHOLD),
@@ -414,20 +415,9 @@ char *snd_pcm_start_mode_names[] = {
        START(DATA),
 };
 
-char *snd_pcm_ready_mode_names[] = {
-       READY(FRAGMENT),
-       READY(ASAP),
-};
-
 char *snd_pcm_xrun_mode_names[] = {
-       XRUN(FRAGMENT),
-       XRUN(ASAP),
        XRUN(NONE),
-};
-
-char *snd_pcm_silence_mode_names[] = {
-       SILENCE(FRAGMENT),
-       SILENCE(ASAP),
+       XRUN(STOP),
 };
 
 char *snd_pcm_tstamp_mode_names[] = {
@@ -435,25 +425,25 @@ char *snd_pcm_tstamp_mode_names[] = {
        TSTAMP(MMAP),
 };
 
-const char *snd_pcm_stream_name(unsigned int stream)
+const char *snd_pcm_stream_name(snd_pcm_stream_t stream)
 {
        assert(stream <= SND_PCM_STREAM_LAST);
        return snd_pcm_stream_names[stream];
 }
 
-const char *snd_pcm_access_name(unsigned int access)
+const char *snd_pcm_access_name(snd_pcm_access_t access)
 {
        assert(access <= SND_PCM_ACCESS_LAST);
        return snd_pcm_access_names[access];
 }
 
-const char *snd_pcm_format_name(unsigned int format)
+const char *snd_pcm_format_name(snd_pcm_format_t format)
 {
        assert(format <= SND_PCM_FORMAT_LAST);
        return snd_pcm_format_names[format];
 }
 
-const char *snd_pcm_format_description(unsigned int format)
+const char *snd_pcm_format_description(snd_pcm_format_t format)
 {
        assert(format <= SND_PCM_FORMAT_LAST);
        return snd_pcm_format_descriptions[format];
@@ -469,55 +459,43 @@ int snd_pcm_format_value(const char* name)
        return -1;
 }
 
-const char *snd_pcm_subformat_name(unsigned int subformat)
+const char *snd_pcm_subformat_name(snd_pcm_subformat_t subformat)
 {
        assert(subformat <= SND_PCM_SUBFORMAT_LAST);
        return snd_pcm_subformat_names[subformat];
 }
 
-const char *snd_pcm_hw_param_name(unsigned int param)
+const char *snd_pcm_hw_param_name(snd_pcm_hw_param_t param)
 {
        assert(param <= SND_PCM_HW_PARAM_LAST);
        return snd_pcm_hw_param_names[param];
 }
 
-const char *snd_pcm_sw_param_name(unsigned int param)
+const char *snd_pcm_sw_param_name(snd_pcm_sw_param_t param)
 {
        assert(param <= SND_PCM_SW_PARAM_LAST);
        return snd_pcm_sw_param_names[param];
 }
 
-const char *snd_pcm_start_mode_name(unsigned int mode)
+const char *snd_pcm_start_mode_name(snd_pcm_start_t mode)
 {
        assert(mode <= SND_PCM_START_LAST);
        return snd_pcm_start_mode_names[mode];
 }
 
-const char *snd_pcm_ready_mode_name(unsigned int mode)
-{
-       assert(mode <= SND_PCM_READY_LAST);
-       return snd_pcm_ready_mode_names[mode];
-}
-
-const char *snd_pcm_xrun_mode_name(unsigned int mode)
+const char *snd_pcm_xrun_mode_name(snd_pcm_xrun_t mode)
 {
        assert(mode <= SND_PCM_XRUN_LAST);
        return snd_pcm_xrun_mode_names[mode];
 }
 
-const char *snd_pcm_silence_mode_name(unsigned int mode)
-{
-       assert(mode <= SND_PCM_SILENCE_LAST);
-       return snd_pcm_silence_mode_names[mode];
-}
-
-const char *snd_pcm_tstamp_mode_name(unsigned int mode)
+const char *snd_pcm_tstamp_mode_name(snd_pcm_tstamp_t mode)
 {
        assert(mode <= SND_PCM_TSTAMP_LAST);
        return snd_pcm_tstamp_mode_names[mode];
 }
 
-const char *snd_pcm_state_name(unsigned int state)
+const char *snd_pcm_state_name(snd_pcm_state_t state)
 {
        assert(state <= SND_PCM_STATE_LAST);
        return snd_pcm_state_names[state];
@@ -536,8 +514,10 @@ int snd_pcm_dump_hw_setup(snd_pcm_t *pcm, FILE *fp)
        fprintf(fp, "rate         : %u\n", pcm->rate);
        fprintf(fp, "exact rate   : %g (%u/%u)\n", (double) pcm->rate_num / pcm->rate_den, pcm->rate_num, pcm->rate_den);
        fprintf(fp, "msbits       : %u\n", pcm->msbits);
-       fprintf(fp, "fragment_size: %lu\n", (long)pcm->fragment_size);
-       fprintf(fp, "fragments    : %u\n", pcm->fragments);
+       fprintf(fp, "buffer_size  : %lu\n", pcm->buffer_size);
+       fprintf(fp, "period_size  : %lu\n", pcm->period_size);
+       fprintf(fp, "period_time  : %u\n", pcm->period_time);
+       fprintf(fp, "tick_time    : %u\n", pcm->tick_time);
        return 0;
 }
 
@@ -548,9 +528,9 @@ int snd_pcm_dump_sw_setup(snd_pcm_t *pcm, FILE *fp)
        assert(pcm->setup);
        fprintf(fp, "start_mode   : %s\n", snd_pcm_start_mode_name(pcm->start_mode));
        fprintf(fp, "xrun_mode    : %s\n", snd_pcm_xrun_mode_name(pcm->xrun_mode));
-       fprintf(fp, "ready_mode   : %s\n", snd_pcm_ready_mode_name(pcm->ready_mode));
-       fprintf(fp, "silence_mode : %s\n", snd_pcm_silence_mode_name(pcm->silence_mode));
        fprintf(fp, "tstamp_mode  : %s\n", snd_pcm_tstamp_mode_name(pcm->tstamp_mode));
+       fprintf(fp, "period_step  : %ld\n", (long)pcm->period_step);
+       fprintf(fp, "sleep_min    : %ld\n", (long)pcm->sleep_min);
        fprintf(fp, "avail_min    : %ld\n", (long)pcm->avail_min);
        fprintf(fp, "xfer_align   : %ld\n", (long)pcm->xfer_align);
        fprintf(fp, "silence_threshold: %ld\n", (long)pcm->silence_threshold);
@@ -588,28 +568,28 @@ int snd_pcm_dump(snd_pcm_t *pcm, FILE *fp)
        return 0;
 }
 
-ssize_t snd_pcm_bytes_to_frames(snd_pcm_t *pcm, ssize_t bytes)
+snd_pcm_sframes_t snd_pcm_bytes_to_frames(snd_pcm_t *pcm, ssize_t bytes)
 {
        assert(pcm);
        assert(pcm->setup);
        return bytes * 8 / pcm->bits_per_frame;
 }
 
-ssize_t snd_pcm_frames_to_bytes(snd_pcm_t *pcm, ssize_t frames)
+ssize_t snd_pcm_frames_to_bytes(snd_pcm_t *pcm, snd_pcm_sframes_t frames)
 {
        assert(pcm);
        assert(pcm->setup);
        return frames * pcm->bits_per_frame / 8;
 }
 
-ssize_t snd_pcm_bytes_to_samples(snd_pcm_t *pcm, ssize_t bytes)
+int snd_pcm_bytes_to_samples(snd_pcm_t *pcm, ssize_t bytes)
 {
        assert(pcm);
        assert(pcm->setup);
        return bytes * 8 / pcm->bits_per_sample;
 }
 
-ssize_t snd_pcm_samples_to_bytes(snd_pcm_t *pcm, ssize_t samples)
+ssize_t snd_pcm_samples_to_bytes(snd_pcm_t *pcm, int samples)
 {
        assert(pcm);
        assert(pcm->setup);
@@ -788,20 +768,20 @@ int snd_pcm_wait(snd_pcm_t *pcm, int timeout)
        return 0;
 }
 
-ssize_t snd_pcm_avail_update(snd_pcm_t *pcm)
+snd_pcm_sframes_t snd_pcm_avail_update(snd_pcm_t *pcm)
 {
        return pcm->fast_ops->avail_update(pcm->fast_op_arg);
 }
 
-ssize_t snd_pcm_mmap_forward(snd_pcm_t *pcm, size_t size)
+snd_pcm_sframes_t snd_pcm_mmap_forward(snd_pcm_t *pcm, snd_pcm_uframes_t size)
 {
        assert(size > 0);
        assert(size <= snd_pcm_mmap_avail(pcm));
        return pcm->fast_ops->mmap_forward(pcm->fast_op_arg, size);
 }
 
-int snd_pcm_area_silence(const snd_pcm_channel_area_t *dst_area, size_t dst_offset,
-                        size_t samples, int format)
+int snd_pcm_area_silence(const snd_pcm_channel_area_t *dst_area, snd_pcm_uframes_t dst_offset,
+                        unsigned int samples, int format)
 {
        /* FIXME: sub byte resolution and odd dst_offset */
        char *dst;
@@ -814,7 +794,7 @@ int snd_pcm_area_silence(const snd_pcm_channel_area_t *dst_area, size_t dst_offs
        width = snd_pcm_format_physical_width(format);
        silence = snd_pcm_format_silence_64(format);
        if (dst_area->step == (unsigned int) width) {
-               size_t dwords = samples * width / 64;
+               unsigned int dwords = samples * width / 64;
                samples -= dwords * 64 / width;
                while (dwords-- > 0)
                        *((u_int64_t*)dst)++ = silence;
@@ -882,8 +862,8 @@ int snd_pcm_area_silence(const snd_pcm_channel_area_t *dst_area, size_t dst_offs
        return 0;
 }
 
-int snd_pcm_areas_silence(const snd_pcm_channel_area_t *dst_areas, size_t dst_offset,
-                         size_t channels, size_t frames, int format)
+int snd_pcm_areas_silence(const snd_pcm_channel_area_t *dst_areas, snd_pcm_uframes_t dst_offset,
+                         unsigned int channels, snd_pcm_uframes_t frames, int format)
 {
        int width = snd_pcm_format_physical_width(format);
        while (channels > 0) {
@@ -923,9 +903,9 @@ int snd_pcm_areas_silence(const snd_pcm_channel_area_t *dst_areas, size_t dst_of
 }
 
 
-int snd_pcm_area_copy(const snd_pcm_channel_area_t *src_area, size_t src_offset,
-                     const snd_pcm_channel_area_t *dst_area, size_t dst_offset,
-                     size_t samples, int format)
+int snd_pcm_area_copy(const snd_pcm_channel_area_t *src_area, snd_pcm_uframes_t src_offset,
+                     const snd_pcm_channel_area_t *dst_area, snd_pcm_uframes_t dst_offset,
+                     unsigned int samples, int format)
 {
        /* FIXME: sub byte resolution and odd dst_offset */
        char *src, *dst;
@@ -1018,9 +998,9 @@ int snd_pcm_area_copy(const snd_pcm_channel_area_t *src_area, size_t src_offset,
        return 0;
 }
 
-int snd_pcm_areas_copy(const snd_pcm_channel_area_t *src_areas, size_t src_offset,
-                      const snd_pcm_channel_area_t *dst_areas, size_t dst_offset,
-                      size_t channels, size_t frames, int format)
+int snd_pcm_areas_copy(const snd_pcm_channel_area_t *src_areas, snd_pcm_uframes_t src_offset,
+                      const snd_pcm_channel_area_t *dst_areas, snd_pcm_uframes_t dst_offset,
+                      unsigned int channels, snd_pcm_uframes_t frames, int format)
 {
        int width = snd_pcm_format_physical_width(format);
        while (channels > 0) {
@@ -1065,12 +1045,12 @@ int snd_pcm_areas_copy(const snd_pcm_channel_area_t *src_areas, size_t src_offse
        return 0;
 }
 
-ssize_t snd_pcm_read_areas(snd_pcm_t *pcm, const snd_pcm_channel_area_t *areas,
-                          size_t offset, size_t size,
+snd_pcm_sframes_t snd_pcm_read_areas(snd_pcm_t *pcm, const snd_pcm_channel_area_t *areas,
+                          snd_pcm_uframes_t offset, snd_pcm_uframes_t size,
                           snd_pcm_xfer_areas_func_t func)
 {
-       size_t xfer = 0;
-       ssize_t err = 0;
+       snd_pcm_uframes_t xfer = 0;
+       snd_pcm_sframes_t err = 0;
        int state = snd_pcm_state(pcm);
        assert(size > 0);
        assert(state >= SND_PCM_STATE_PREPARED);
@@ -1082,15 +1062,15 @@ ssize_t snd_pcm_read_areas(snd_pcm_t *pcm, const snd_pcm_channel_area_t *areas,
                state = SND_PCM_STATE_RUNNING;
        }
        while (xfer < size) {
-               ssize_t avail;
-               size_t frames;
+               snd_pcm_sframes_t avail;
+               snd_pcm_uframes_t frames;
        again:
                avail = snd_pcm_avail_update(pcm);
                if (avail < 0) {
                        err = avail;
                        break;
                }
-               if ((size_t)avail < pcm->avail_min) {
+               if ((snd_pcm_uframes_t)avail < pcm->avail_min) {
                        if (state != SND_PCM_STATE_RUNNING) {
                                err = -EPIPE;
                                break;
@@ -1106,12 +1086,12 @@ ssize_t snd_pcm_read_areas(snd_pcm_t *pcm, const snd_pcm_channel_area_t *areas,
                        goto again;
                }
                frames = size - xfer;
-               if (frames > (size_t)avail)
+               if (frames > (snd_pcm_uframes_t)avail)
                        frames = avail;
                err = func(pcm, areas, offset, frames, 0);
                if (err < 0)
                        break;
-               assert((size_t)err == frames);
+               assert((snd_pcm_uframes_t)err == frames);
                xfer += err;
                offset += err;
        }
@@ -1120,18 +1100,18 @@ ssize_t snd_pcm_read_areas(snd_pcm_t *pcm, const snd_pcm_channel_area_t *areas,
        return err;
 }
 
-ssize_t snd_pcm_write_areas(snd_pcm_t *pcm, const snd_pcm_channel_area_t *areas,
-                           size_t offset, size_t size,
+snd_pcm_sframes_t snd_pcm_write_areas(snd_pcm_t *pcm, const snd_pcm_channel_area_t *areas,
+                           snd_pcm_uframes_t offset, snd_pcm_uframes_t size,
                            snd_pcm_xfer_areas_func_t func)
 {
-       size_t xfer = 0;
-       ssize_t err = 0;
+       snd_pcm_uframes_t xfer = 0;
+       snd_pcm_sframes_t err = 0;
        int state = snd_pcm_state(pcm);
        assert(size > 0);
        assert(state >= SND_PCM_STATE_PREPARED);
        while (xfer < size) {
-               ssize_t avail;
-               size_t frames;
+               snd_pcm_sframes_t avail;
+               snd_pcm_uframes_t frames;
        again:
                if (state == SND_PCM_STATE_XRUN) {
                        err = -EPIPE;
@@ -1142,7 +1122,7 @@ ssize_t snd_pcm_write_areas(snd_pcm_t *pcm, const snd_pcm_channel_area_t *areas,
                        err = avail;
                        break;
                }
-               if ((size_t)avail < pcm->avail_min) {
+               if ((snd_pcm_uframes_t)avail < pcm->avail_min) {
                        if (state != SND_PCM_STATE_RUNNING) {
                                err = -EPIPE;
                                break;
@@ -1158,12 +1138,12 @@ ssize_t snd_pcm_write_areas(snd_pcm_t *pcm, const snd_pcm_channel_area_t *areas,
                        goto again;
                }
                frames = size - xfer;
-               if (frames > (size_t)avail)
+               if (frames > (snd_pcm_uframes_t)avail)
                        frames = avail;
                err = func(pcm, areas, offset, frames, 0);
                if (err < 0)
                        break;
-               assert((size_t)err == frames);
+               assert((snd_pcm_uframes_t)err == frames);
                xfer += err;
                offset += err;
                if (state == SND_PCM_STATE_PREPARED &&
@@ -1179,7 +1159,7 @@ ssize_t snd_pcm_write_areas(snd_pcm_t *pcm, const snd_pcm_channel_area_t *areas,
        return err;
 }
 
-size_t _snd_pcm_mmap_hw_ptr(snd_pcm_t *pcm)
+snd_pcm_uframes_t _snd_pcm_mmap_hw_ptr(snd_pcm_t *pcm)
 {
        return *pcm->hw_ptr;
 }
index 41acc1087e0f9efbd14fc42c7e823dd718d7ff0d..31c3f76ccc4b06ce2c25f98a61066fcf40e372fc 100644 (file)
@@ -57,10 +57,10 @@ typedef struct {
 } adpcm_state_t;
 
 typedef void (*adpcm_f)(const snd_pcm_channel_area_t *src_areas,
-                       size_t src_offset,
+                       snd_pcm_uframes_t src_offset,
                        const snd_pcm_channel_area_t *dst_areas,
-                       size_t dst_offset,
-                       size_t channels, size_t frames, int getputidx,
+                       snd_pcm_uframes_t dst_offset,
+                       unsigned int channels, snd_pcm_uframes_t frames, int getputidx,
                        adpcm_state_t *states);
 
 typedef struct {
@@ -196,23 +196,23 @@ static int adpcm_decoder(unsigned char code, adpcm_state_t * state)
 }
 
 static void adpcm_decode(const snd_pcm_channel_area_t *src_areas,
-                        size_t src_offset,
+                        snd_pcm_uframes_t src_offset,
                         const snd_pcm_channel_area_t *dst_areas,
-                        size_t dst_offset,
-                        size_t channels, size_t frames, int putidx,
+                        snd_pcm_uframes_t dst_offset,
+                        unsigned int channels, snd_pcm_uframes_t frames, int putidx,
                         adpcm_state_t *states)
 {
 #define PUT16_LABELS
 #include "plugin_ops.h"
 #undef PUT16_LABELS
        void *put = put16_labels[putidx];
-       size_t channel;
+       unsigned int channel;
        for (channel = 0; channel < channels; ++channel, ++states) {
                char *src;
                int srcbit;
                char *dst;
                int src_step, srcbit_step, dst_step;
-               size_t frames1;
+               snd_pcm_uframes_t frames1;
                const snd_pcm_channel_area_t *src_area = &src_areas[channel];
                const snd_pcm_channel_area_t *dst_area = &dst_areas[channel];
 #if 0
@@ -257,24 +257,24 @@ static void adpcm_decode(const snd_pcm_channel_area_t *src_areas,
 }
 
 static void adpcm_encode(const snd_pcm_channel_area_t *src_areas,
-                        size_t src_offset,
+                        snd_pcm_uframes_t src_offset,
                         const snd_pcm_channel_area_t *dst_areas,
-                        size_t dst_offset,
-                        size_t channels, size_t frames, int getidx,
+                        snd_pcm_uframes_t dst_offset,
+                        unsigned int channels, snd_pcm_uframes_t frames, int getidx,
                         adpcm_state_t *states)
 {
 #define GET16_LABELS
 #include "plugin_ops.h"
 #undef GET16_LABELS
        void *get = get16_labels[getidx];
-       size_t channel;
+       unsigned int channel;
        int16_t sample = 0;
        for (channel = 0; channel < channels; ++channel, ++states) {
                char *src;
                char *dst;
                int dstbit;
                int src_step, dst_step, dstbit_step;
-               size_t frames1;
+               snd_pcm_uframes_t frames1;
                const snd_pcm_channel_area_t *src_area = &src_areas[channel];
                const snd_pcm_channel_area_t *dst_area = &dst_areas[channel];
 #if 0
@@ -334,51 +334,58 @@ static int snd_pcm_adpcm_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
        snd_pcm_adpcm_t *adpcm = pcm->private;
        snd_pcm_t *slave = adpcm->plug.slave;
        int err;
+       unsigned int cmask, lcmask;
        snd_pcm_hw_params_t sparams;
        mask_t *access_mask = alloca(mask_sizeof());
        mask_t *saccess_mask = alloca(mask_sizeof());
        mask_load(access_mask, SND_PCM_ACCBIT_PLUGIN);
        mask_load(saccess_mask, SND_PCM_ACCBIT_MMAP);
-       err = _snd_pcm_hw_param_mask(params, 1, SND_PCM_HW_PARAM_ACCESS,
+       cmask = params->cmask;
+       params->cmask = 0;
+       err = _snd_pcm_hw_param_mask(params, SND_PCM_HW_PARAM_ACCESS,
                                      access_mask);
        if (err < 0)
                return err;
        if (adpcm->sformat == SND_PCM_FORMAT_IMA_ADPCM) {
                mask_t *format_mask = alloca(mask_sizeof());
                mask_load(format_mask, SND_PCM_FMTBIT_LINEAR);
-               err = _snd_pcm_hw_param_mask(params, 1,
+               err = _snd_pcm_hw_param_mask(params,
                                              SND_PCM_HW_PARAM_FORMAT,
                                              format_mask);
                if (err < 0)
                        return err;
        } else {
-               err = _snd_pcm_hw_param_set(params, 1,
-                                            SND_PCM_HW_PARAM_FORMAT,
-                                            SND_PCM_FORMAT_IMA_ADPCM);
+               err = _snd_pcm_hw_param_set(params,
+                                           SND_PCM_HW_PARAM_FORMAT,
+                                           SND_PCM_FORMAT_IMA_ADPCM, 0);
                if (err < 0)
                        return err;
        }
-       err = _snd_pcm_hw_param_set(params, 1, SND_PCM_HW_PARAM_SUBFORMAT,
-                                    SND_PCM_SUBFORMAT_STD);
+       err = _snd_pcm_hw_param_set(params, SND_PCM_HW_PARAM_SUBFORMAT,
+                                    SND_PCM_SUBFORMAT_STD, 0);
        if (err < 0)
                return err;
+       lcmask = params->cmask;
+       params->cmask |= cmask;
 
        _snd_pcm_hw_params_any(&sparams);
-       _snd_pcm_hw_param_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
+       _snd_pcm_hw_param_mask(&sparams, SND_PCM_HW_PARAM_ACCESS,
                                saccess_mask);
-       _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_FORMAT,
-                              adpcm->sformat);
-       _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_SUBFORMAT,
-                              SND_PCM_SUBFORMAT_STD);
+       _snd_pcm_hw_param_set(&sparams, SND_PCM_HW_PARAM_FORMAT,
+                             adpcm->sformat, 0);
+       _snd_pcm_hw_param_set(&sparams, SND_PCM_HW_PARAM_SUBFORMAT,
+                              SND_PCM_SUBFORMAT_STD, 0);
        err = snd_pcm_hw_refine2(params, &sparams,
-                                snd_pcm_hw_refine, slave,
+                                snd_pcm_generic_hw_link, slave,
                                 SND_PCM_HW_PARBIT_CHANNELS |
                                 SND_PCM_HW_PARBIT_RATE |
-                                SND_PCM_HW_PARBIT_FRAGMENT_SIZE |
+                                SND_PCM_HW_PARBIT_PERIOD_SIZE |
                                 SND_PCM_HW_PARBIT_BUFFER_SIZE |
-                                SND_PCM_HW_PARBIT_FRAGMENTS |
-                                SND_PCM_HW_PARBIT_FRAGMENT_LENGTH |
-                                SND_PCM_HW_PARBIT_BUFFER_LENGTH);
+                                SND_PCM_HW_PARBIT_PERIODS |
+                                SND_PCM_HW_PARBIT_PERIOD_TIME |
+                                SND_PCM_HW_PARBIT_BUFFER_TIME |
+                                SND_PCM_HW_PARBIT_TICK_TIME);
+       params->cmask |= lcmask;
        if (err < 0)
                return err;
        params->info &= ~(SND_PCM_INFO_MMAP | SND_PCM_INFO_MMAP_VALID);
@@ -391,31 +398,39 @@ static int snd_pcm_adpcm_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
        snd_pcm_t *slave = adpcm->plug.slave;
        int err;
        snd_pcm_hw_params_t sparams;
+       unsigned int links;
        mask_t *saccess_mask = alloca(mask_sizeof());
        mask_load(saccess_mask, SND_PCM_ACCBIT_MMAP);
 
        _snd_pcm_hw_params_any(&sparams);
-       _snd_pcm_hw_param_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
+       _snd_pcm_hw_param_mask(&sparams, SND_PCM_HW_PARAM_ACCESS,
                                saccess_mask);
-       _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_FORMAT,
-                              adpcm->sformat);
-       _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_SUBFORMAT,
-                              SND_PCM_SUBFORMAT_STD);
-       err = snd_pcm_hw_params2(params, &sparams,
-                                snd_pcm_hw_params, slave,
-                                SND_PCM_HW_PARBIT_CHANNELS |
-                                SND_PCM_HW_PARBIT_RATE |
-                                SND_PCM_HW_PARBIT_FRAGMENT_SIZE |
-                                SND_PCM_HW_PARBIT_BUFFER_SIZE |
-                                SND_PCM_HW_PARBIT_FRAGMENTS |
-                                SND_PCM_HW_PARBIT_FRAGMENT_LENGTH |
-                                SND_PCM_HW_PARBIT_BUFFER_LENGTH);
+       _snd_pcm_hw_param_set(&sparams, SND_PCM_HW_PARAM_FORMAT,
+                             adpcm->sformat, 0);
+       _snd_pcm_hw_param_set(&sparams, SND_PCM_HW_PARAM_SUBFORMAT,
+                             SND_PCM_SUBFORMAT_STD, 0);
+       links = SND_PCM_HW_PARBIT_CHANNELS |
+               SND_PCM_HW_PARBIT_RATE |
+               SND_PCM_HW_PARBIT_PERIOD_SIZE |
+               SND_PCM_HW_PARBIT_BUFFER_SIZE |
+               SND_PCM_HW_PARBIT_PERIODS |
+               SND_PCM_HW_PARBIT_PERIOD_TIME |
+               SND_PCM_HW_PARBIT_BUFFER_TIME |
+               SND_PCM_HW_PARBIT_TICK_TIME;
+       err = snd_pcm_hw_params_refine(&sparams, links, params);
+       assert(err >= 0);
+       err = _snd_pcm_hw_refine(&sparams);
+       assert(err >= 0);
+       err = snd_pcm_hw_params(slave, &sparams);
+       params->cmask = 0;
+       sparams.cmask = ~0U;
+       snd_pcm_hw_params_refine(params, links, &sparams);
        if (err < 0)
                return err;
        params->info &= ~(SND_PCM_INFO_MMAP | SND_PCM_INFO_MMAP_VALID);
        if (pcm->stream == SND_PCM_STREAM_PLAYBACK) {
                if (adpcm->sformat == SND_PCM_FORMAT_IMA_ADPCM) {
-                       adpcm->getput_idx = get_index(snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FORMAT), SND_PCM_FORMAT_S16);
+                       adpcm->getput_idx = get_index(snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FORMAT, 0), SND_PCM_FORMAT_S16);
                        adpcm->func = adpcm_encode;
                } else {
                        adpcm->getput_idx = put_index(SND_PCM_FORMAT_S16, adpcm->sformat);
@@ -423,7 +438,7 @@ static int snd_pcm_adpcm_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
                }
        } else {
                if (adpcm->sformat == SND_PCM_FORMAT_IMA_ADPCM) {
-                       adpcm->getput_idx = put_index(SND_PCM_FORMAT_S16, snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FORMAT));
+                       adpcm->getput_idx = put_index(SND_PCM_FORMAT_S16, snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FORMAT, 0));
                        adpcm->func = adpcm_decode;
                } else {
                        adpcm->getput_idx = get_index(adpcm->sformat, SND_PCM_FORMAT_S16);
@@ -432,7 +447,7 @@ static int snd_pcm_adpcm_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
        }
        if (adpcm->states)
                free(adpcm->states);
-       adpcm->states = malloc(snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_CHANNELS) * sizeof(*adpcm->states));
+       adpcm->states = malloc(snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_CHANNELS, 0) * sizeof(*adpcm->states));
        return 0;
 }
 
@@ -447,21 +462,21 @@ static int snd_pcm_adpcm_init(snd_pcm_t *pcm)
        return 0;
 }
 
-static ssize_t snd_pcm_adpcm_write_areas(snd_pcm_t *pcm,
+static snd_pcm_sframes_t snd_pcm_adpcm_write_areas(snd_pcm_t *pcm,
                                         const snd_pcm_channel_area_t *areas,
-                                        size_t offset,
-                                        size_t size,
-                                        size_t *slave_sizep)
+                                        snd_pcm_uframes_t offset,
+                                        snd_pcm_uframes_t size,
+                                        snd_pcm_uframes_t *slave_sizep)
 {
        snd_pcm_adpcm_t *adpcm = pcm->private;
        snd_pcm_t *slave = adpcm->plug.slave;
-       size_t xfer = 0;
-       ssize_t err = 0;
+       snd_pcm_uframes_t xfer = 0;
+       snd_pcm_sframes_t err = 0;
        if (slave_sizep && *slave_sizep < size)
                size = *slave_sizep;
        assert(size > 0);
        while (xfer < size) {
-               size_t frames = snd_pcm_mmap_playback_xfer(slave, size - xfer);
+               snd_pcm_uframes_t frames = snd_pcm_mmap_playback_xfer(slave, size - xfer);
                adpcm->func(areas, offset, 
                            snd_pcm_mmap_areas(slave), snd_pcm_mmap_offset(slave),
                            pcm->channels, frames,
@@ -469,7 +484,7 @@ static ssize_t snd_pcm_adpcm_write_areas(snd_pcm_t *pcm,
                err = snd_pcm_mmap_forward(slave, frames);
                if (err < 0)
                        break;
-               assert((size_t)err == frames);
+               assert((snd_pcm_uframes_t)err == frames);
                offset += err;
                xfer += err;
                snd_pcm_mmap_hw_forward(pcm, err);
@@ -482,21 +497,21 @@ static ssize_t snd_pcm_adpcm_write_areas(snd_pcm_t *pcm,
        return err;
 }
 
-static ssize_t snd_pcm_adpcm_read_areas(snd_pcm_t *pcm,
+static snd_pcm_sframes_t snd_pcm_adpcm_read_areas(snd_pcm_t *pcm,
                                        const snd_pcm_channel_area_t *areas,
-                                       size_t offset,
-                                       size_t size,
-                                       size_t *slave_sizep)
+                                       snd_pcm_uframes_t offset,
+                                       snd_pcm_uframes_t size,
+                                       snd_pcm_uframes_t *slave_sizep)
 {
        snd_pcm_adpcm_t *adpcm = pcm->private;
        snd_pcm_t *slave = adpcm->plug.slave;
-       size_t xfer = 0;
-       ssize_t err = 0;
+       snd_pcm_uframes_t xfer = 0;
+       snd_pcm_sframes_t err = 0;
        if (slave_sizep && *slave_sizep < size)
                size = *slave_sizep;
        assert(size > 0);
        while (xfer < size) {
-               size_t frames = snd_pcm_mmap_capture_xfer(slave, size - xfer);
+               snd_pcm_uframes_t frames = snd_pcm_mmap_capture_xfer(slave, size - xfer);
                adpcm->func(snd_pcm_mmap_areas(slave), snd_pcm_mmap_offset(slave),
                            areas, offset, 
                            pcm->channels, frames,
@@ -504,7 +519,7 @@ static ssize_t snd_pcm_adpcm_read_areas(snd_pcm_t *pcm,
                err = snd_pcm_mmap_forward(slave, frames);
                if (err < 0)
                        break;
-               assert((size_t)err == frames);
+               assert((snd_pcm_uframes_t)err == frames);
                offset += err;
                xfer += err;
                snd_pcm_mmap_hw_forward(pcm, err);
index feb600086a656e12645d366563355ca3d5843a00..1be95dbf210da8a331e3c19a2ed910f30608ed31 100644 (file)
 #include "pcm_plugin.h"
 
 typedef void (*alaw_f)(const snd_pcm_channel_area_t *src_areas,
-                       size_t src_offset,
+                       snd_pcm_uframes_t src_offset,
                        const snd_pcm_channel_area_t *dst_areas,
-                       size_t dst_offset,
-                       size_t channels, size_t frames, int getputidx);
+                       snd_pcm_uframes_t dst_offset,
+                       unsigned int channels, snd_pcm_uframes_t frames, int getputidx);
 
 typedef struct {
        /* This field need to be the first */
@@ -121,21 +121,21 @@ static int alaw_to_s16(unsigned char a_val)
 }
 
 static void alaw_decode(const snd_pcm_channel_area_t *src_areas,
-                       size_t src_offset,
+                       snd_pcm_uframes_t src_offset,
                        const snd_pcm_channel_area_t *dst_areas,
-                       size_t dst_offset,
-                       size_t channels, size_t frames, int putidx)
+                       snd_pcm_uframes_t dst_offset,
+                       unsigned int channels, snd_pcm_uframes_t frames, int putidx)
 {
 #define PUT16_LABELS
 #include "plugin_ops.h"
 #undef PUT16_LABELS
        void *put = put16_labels[putidx];
-       size_t channel;
+       unsigned int channel;
        for (channel = 0; channel < channels; ++channel) {
                char *src;
                char *dst;
                int src_step, dst_step;
-               size_t frames1;
+               snd_pcm_uframes_t frames1;
                const snd_pcm_channel_area_t *src_area = &src_areas[channel];
                const snd_pcm_channel_area_t *dst_area = &dst_areas[channel];
 #if 0
@@ -166,22 +166,22 @@ static void alaw_decode(const snd_pcm_channel_area_t *src_areas,
 }
 
 static void alaw_encode(const snd_pcm_channel_area_t *src_areas,
-                        size_t src_offset,
+                        snd_pcm_uframes_t src_offset,
                         const snd_pcm_channel_area_t *dst_areas,
-                        size_t dst_offset,
-                        size_t channels, size_t frames, int getidx)
+                        snd_pcm_uframes_t dst_offset,
+                        unsigned int channels, snd_pcm_uframes_t frames, int getidx)
 {
 #define GET16_LABELS
 #include "plugin_ops.h"
 #undef GET16_LABELS
        void *get = get16_labels[getidx];
-       size_t channel;
+       unsigned int channel;
        int16_t sample = 0;
        for (channel = 0; channel < channels; ++channel) {
                char *src;
                char *dst;
                int src_step, dst_step;
-               size_t frames1;
+               snd_pcm_uframes_t frames1;
                const snd_pcm_channel_area_t *src_area = &src_areas[channel];
                const snd_pcm_channel_area_t *dst_area = &dst_areas[channel];
 #if 0
@@ -216,51 +216,58 @@ static int snd_pcm_alaw_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
        snd_pcm_alaw_t *alaw = pcm->private;
        snd_pcm_t *slave = alaw->plug.slave;
        int err;
+       unsigned int cmask, lcmask;
        snd_pcm_hw_params_t sparams;
        mask_t *access_mask = alloca(mask_sizeof());
        mask_t *saccess_mask = alloca(mask_sizeof());
        mask_load(access_mask, SND_PCM_ACCBIT_PLUGIN);
        mask_load(saccess_mask, SND_PCM_ACCBIT_MMAP);
-       err = _snd_pcm_hw_param_mask(params, 1, SND_PCM_HW_PARAM_ACCESS,
+       cmask = params->cmask;
+       params->cmask = 0;
+       err = _snd_pcm_hw_param_mask(params, SND_PCM_HW_PARAM_ACCESS,
                                      access_mask);
        if (err < 0)
                return err;
        if (alaw->sformat == SND_PCM_FORMAT_A_LAW) {
                mask_t *format_mask = alloca(mask_sizeof());
                mask_load(format_mask, SND_PCM_FMTBIT_LINEAR);
-               err = _snd_pcm_hw_param_mask(params, 1,
+               err = _snd_pcm_hw_param_mask(params,
                                              SND_PCM_HW_PARAM_FORMAT,
                                              format_mask);
                if (err < 0)
                        return err;
        } else {
-               err = _snd_pcm_hw_param_set(params, 1, 
+               err = _snd_pcm_hw_param_set(params,
                                             SND_PCM_HW_PARAM_FORMAT,
-                                            SND_PCM_FORMAT_A_LAW);
+                                            SND_PCM_FORMAT_A_LAW, 0);
                if (err < 0)
                        return err;
        }
-       err = _snd_pcm_hw_param_set(params, 1, SND_PCM_HW_PARAM_SUBFORMAT,
-                                    SND_PCM_SUBFORMAT_STD);
+       err = _snd_pcm_hw_param_set(params, SND_PCM_HW_PARAM_SUBFORMAT,
+                                    SND_PCM_SUBFORMAT_STD, 0);
        if (err < 0)
                return err;
+       lcmask = params->cmask;
+       params->cmask |= cmask;
 
        _snd_pcm_hw_params_any(&sparams);
-       _snd_pcm_hw_param_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
-                               saccess_mask);
-       _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_FORMAT,
-                              alaw->sformat);
-       _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_SUBFORMAT,
-                              SND_PCM_SUBFORMAT_STD);
+       _snd_pcm_hw_param_mask(&sparams, SND_PCM_HW_PARAM_ACCESS,
+                              saccess_mask);
+       _snd_pcm_hw_param_set(&sparams, SND_PCM_HW_PARAM_FORMAT,
+                             alaw->sformat, 0);
+       _snd_pcm_hw_param_set(&sparams, SND_PCM_HW_PARAM_SUBFORMAT,
+                             SND_PCM_SUBFORMAT_STD, 0);
        err = snd_pcm_hw_refine2(params, &sparams,
-                                snd_pcm_hw_refine, slave,
+                                snd_pcm_generic_hw_link, slave,
                                 SND_PCM_HW_PARBIT_CHANNELS |
                                 SND_PCM_HW_PARBIT_RATE |
-                                SND_PCM_HW_PARBIT_FRAGMENT_SIZE |
+                                SND_PCM_HW_PARBIT_PERIOD_SIZE |
                                 SND_PCM_HW_PARBIT_BUFFER_SIZE |
-                                SND_PCM_HW_PARBIT_FRAGMENTS |
-                                SND_PCM_HW_PARBIT_FRAGMENT_LENGTH |
-                                SND_PCM_HW_PARBIT_BUFFER_LENGTH);
+                                SND_PCM_HW_PARBIT_PERIODS |
+                                SND_PCM_HW_PARBIT_PERIOD_TIME |
+                                SND_PCM_HW_PARBIT_BUFFER_TIME |
+                                SND_PCM_HW_PARBIT_TICK_TIME);
+       params->cmask |= lcmask;
        if (err < 0)
                return err;
        params->info &= ~(SND_PCM_INFO_MMAP | SND_PCM_INFO_MMAP_VALID);
@@ -273,31 +280,39 @@ static int snd_pcm_alaw_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
        snd_pcm_t *slave = alaw->plug.slave;
        int err;
        snd_pcm_hw_params_t sparams;
+       unsigned int links;
        mask_t *saccess_mask = alloca(mask_sizeof());
        mask_load(saccess_mask, SND_PCM_ACCBIT_MMAP);
 
        _snd_pcm_hw_params_any(&sparams);
-       _snd_pcm_hw_param_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
-                               saccess_mask);
-       _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_FORMAT,
-                              alaw->sformat);
-       _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_SUBFORMAT,
-                              SND_PCM_SUBFORMAT_STD);
-       err = snd_pcm_hw_params2(params, &sparams,
-                                snd_pcm_hw_params, slave,
-                                SND_PCM_HW_PARBIT_CHANNELS |
-                                SND_PCM_HW_PARBIT_RATE |
-                                SND_PCM_HW_PARBIT_FRAGMENT_SIZE |
-                                SND_PCM_HW_PARBIT_BUFFER_SIZE |
-                                SND_PCM_HW_PARBIT_FRAGMENTS |
-                                SND_PCM_HW_PARBIT_FRAGMENT_LENGTH |
-                                SND_PCM_HW_PARBIT_BUFFER_LENGTH);
+       _snd_pcm_hw_param_mask(&sparams, SND_PCM_HW_PARAM_ACCESS,
+                              saccess_mask);
+       _snd_pcm_hw_param_set(&sparams, SND_PCM_HW_PARAM_FORMAT,
+                             alaw->sformat, 0);
+       _snd_pcm_hw_param_set(&sparams, SND_PCM_HW_PARAM_SUBFORMAT,
+                             SND_PCM_SUBFORMAT_STD, 0);
+       links = SND_PCM_HW_PARBIT_CHANNELS |
+               SND_PCM_HW_PARBIT_RATE |
+               SND_PCM_HW_PARBIT_PERIOD_SIZE |
+               SND_PCM_HW_PARBIT_BUFFER_SIZE |
+               SND_PCM_HW_PARBIT_PERIODS |
+               SND_PCM_HW_PARBIT_PERIOD_TIME |
+               SND_PCM_HW_PARBIT_BUFFER_TIME |
+               SND_PCM_HW_PARBIT_TICK_TIME;
+       err = snd_pcm_hw_params_refine(&sparams, links, params);
+       assert(err >= 0);
+       err = _snd_pcm_hw_refine(&sparams);
+       assert(err >= 0);
+       err = snd_pcm_hw_params(slave, &sparams);
+       params->cmask = 0;
+       sparams.cmask = ~0U;
+       snd_pcm_hw_params_refine(params, links, &sparams);
        if (err < 0)
                return err;
        params->info &= ~(SND_PCM_INFO_MMAP | SND_PCM_INFO_MMAP_VALID);
        if (pcm->stream == SND_PCM_STREAM_PLAYBACK) {
                if (alaw->sformat == SND_PCM_FORMAT_A_LAW) {
-                       alaw->getput_idx = get_index(snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FORMAT), SND_PCM_FORMAT_S16);
+                       alaw->getput_idx = get_index(snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FORMAT, 0), SND_PCM_FORMAT_S16);
                        alaw->func = alaw_encode;
                } else {
                        alaw->getput_idx = put_index(SND_PCM_FORMAT_S16, alaw->sformat);
@@ -305,7 +320,7 @@ static int snd_pcm_alaw_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
                }
        } else {
                if (alaw->sformat == SND_PCM_FORMAT_A_LAW) {
-                       alaw->getput_idx = put_index(SND_PCM_FORMAT_S16, snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FORMAT));
+                       alaw->getput_idx = put_index(SND_PCM_FORMAT_S16, snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FORMAT, 0));
                        alaw->func = alaw_decode;
                } else {
                        alaw->getput_idx = get_index(alaw->sformat, SND_PCM_FORMAT_S16);
@@ -315,21 +330,21 @@ static int snd_pcm_alaw_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
        return 0;
 }
 
-static ssize_t snd_pcm_alaw_write_areas(snd_pcm_t *pcm,
+static snd_pcm_sframes_t snd_pcm_alaw_write_areas(snd_pcm_t *pcm,
                                        const snd_pcm_channel_area_t *areas,
-                                       size_t offset,
-                                       size_t size,
-                                       size_t *slave_sizep)
+                                       snd_pcm_uframes_t offset,
+                                       snd_pcm_uframes_t size,
+                                       snd_pcm_uframes_t *slave_sizep)
 {
        snd_pcm_alaw_t *alaw = pcm->private;
        snd_pcm_t *slave = alaw->plug.slave;
-       size_t xfer = 0;
-       ssize_t err = 0;
+       snd_pcm_uframes_t xfer = 0;
+       snd_pcm_sframes_t err = 0;
        if (slave_sizep && *slave_sizep < size)
                size = *slave_sizep;
        assert(size > 0);
        while (xfer < size) {
-               size_t frames = snd_pcm_mmap_playback_xfer(slave, size - xfer);
+               snd_pcm_uframes_t frames = snd_pcm_mmap_playback_xfer(slave, size - xfer);
                alaw->func(areas, offset, 
                            snd_pcm_mmap_areas(slave), snd_pcm_mmap_offset(slave),
                            pcm->channels, frames,
@@ -337,7 +352,7 @@ static ssize_t snd_pcm_alaw_write_areas(snd_pcm_t *pcm,
                err = snd_pcm_mmap_forward(slave, frames);
                if (err < 0)
                        break;
-               assert((size_t)err == frames);
+               assert((snd_pcm_uframes_t)err == frames);
                offset += err;
                xfer += err;
                snd_pcm_mmap_hw_forward(pcm, err);
@@ -350,21 +365,21 @@ static ssize_t snd_pcm_alaw_write_areas(snd_pcm_t *pcm,
        return err;
 }
 
-static ssize_t snd_pcm_alaw_read_areas(snd_pcm_t *pcm,
+static snd_pcm_sframes_t snd_pcm_alaw_read_areas(snd_pcm_t *pcm,
                                       const snd_pcm_channel_area_t *areas,
-                                      size_t offset,
-                                      size_t size,
-                                      size_t *slave_sizep)
+                                      snd_pcm_uframes_t offset,
+                                      snd_pcm_uframes_t size,
+                                      snd_pcm_uframes_t *slave_sizep)
 {
        snd_pcm_alaw_t *alaw = pcm->private;
        snd_pcm_t *slave = alaw->plug.slave;
-       size_t xfer = 0;
-       ssize_t err = 0;
+       snd_pcm_uframes_t xfer = 0;
+       snd_pcm_sframes_t err = 0;
        if (slave_sizep && *slave_sizep < size)
                size = *slave_sizep;
        assert(size > 0);
        while (xfer < size) {
-               size_t frames = snd_pcm_mmap_capture_xfer(slave, size - xfer);
+               snd_pcm_uframes_t frames = snd_pcm_mmap_capture_xfer(slave, size - xfer);
                alaw->func(snd_pcm_mmap_areas(slave), snd_pcm_mmap_offset(slave),
                           areas, offset, 
                           pcm->channels, frames,
@@ -372,7 +387,7 @@ static ssize_t snd_pcm_alaw_read_areas(snd_pcm_t *pcm,
                err = snd_pcm_mmap_forward(slave, frames);
                if (err < 0)
                        break;
-               assert((size_t)err == frames);
+               assert((snd_pcm_uframes_t)err == frames);
                offset += err;
                xfer += err;
                snd_pcm_mmap_hw_forward(pcm, err);
index cdba7ccee19d4d3a1c131949e4ada994afe4b935..e2bb724e98e5a924e708c8969ec45d794891937b 100644 (file)
@@ -33,21 +33,27 @@ static int snd_pcm_copy_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
        snd_pcm_copy_t *copy = pcm->private;
        snd_pcm_t *slave = copy->plug.slave;
        int err;
+       unsigned int cmask, lcmask;
        snd_pcm_hw_params_t sparams;
        mask_t *access_mask = alloca(mask_sizeof());
        mask_t *saccess_mask = alloca(mask_sizeof());
        mask_load(access_mask, SND_PCM_ACCBIT_PLUGIN);
        mask_load(saccess_mask, SND_PCM_ACCBIT_MMAP);
-       err = _snd_pcm_hw_param_mask(params, 1, SND_PCM_HW_PARAM_ACCESS,
-                                     access_mask);
+       cmask = params->cmask;
+       params->cmask = 0;
+       err = _snd_pcm_hw_param_mask(params, SND_PCM_HW_PARAM_ACCESS,
+                                    access_mask);
        if (err < 0)
                return err;
+       lcmask = params->cmask;
+       params->cmask |= cmask;
        _snd_pcm_hw_params_any(&sparams);
-       _snd_pcm_hw_param_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
+       _snd_pcm_hw_param_mask(&sparams, SND_PCM_HW_PARAM_ACCESS,
                                saccess_mask);
        err = snd_pcm_hw_refine2(params, &sparams,
-                                snd_pcm_hw_refine, slave, 
+                                snd_pcm_generic_hw_link, slave, 
                                 ~SND_PCM_HW_PARBIT_ACCESS);
+       params->cmask |= lcmask;
        if (err < 0)
                return err;
        params->info &= ~(SND_PCM_INFO_MMAP | SND_PCM_INFO_MMAP_VALID);
@@ -59,37 +65,44 @@ static int snd_pcm_copy_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
        snd_pcm_copy_t *copy = pcm->private;
        snd_pcm_t *slave = copy->plug.slave;
        int err;
+       unsigned int links;
        snd_pcm_hw_params_t sparams;
        mask_t *saccess_mask = alloca(mask_sizeof());
        mask_load(saccess_mask, SND_PCM_ACCBIT_MMAP);
 
        _snd_pcm_hw_params_any(&sparams);
-       _snd_pcm_hw_param_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
+       _snd_pcm_hw_param_mask(&sparams, SND_PCM_HW_PARAM_ACCESS,
                                saccess_mask);
-       err = snd_pcm_hw_params2(params, &sparams,
-                                snd_pcm_hw_params, slave, 
-                                ~SND_PCM_HW_PARBIT_ACCESS);
+       links = ~SND_PCM_HW_PARBIT_ACCESS;
+       err = snd_pcm_hw_params_refine(&sparams, links, params);
+       assert(err >= 0);
+       err = _snd_pcm_hw_refine(&sparams);
+       assert(err >= 0);
+       err = snd_pcm_hw_params(slave, &sparams);
+       params->cmask = 0;
+       sparams.cmask = ~0U;
+       snd_pcm_hw_params_refine(params, links, &sparams);
        if (err < 0)
                return err;
        params->info &= ~(SND_PCM_INFO_MMAP | SND_PCM_INFO_MMAP_VALID);
        return err;
 }
 
-static ssize_t snd_pcm_copy_write_areas(snd_pcm_t *pcm,
+static snd_pcm_sframes_t snd_pcm_copy_write_areas(snd_pcm_t *pcm,
                                        const snd_pcm_channel_area_t *areas,
-                                       size_t offset,
-                                       size_t size,
-                                       size_t *slave_sizep)
+                                       snd_pcm_uframes_t offset,
+                                       snd_pcm_uframes_t size,
+                                       snd_pcm_uframes_t *slave_sizep)
 {
        snd_pcm_copy_t *copy = pcm->private;
        snd_pcm_t *slave = copy->plug.slave;
-       size_t xfer = 0;
-       ssize_t err = 0;
+       snd_pcm_uframes_t xfer = 0;
+       snd_pcm_sframes_t err = 0;
        if (slave_sizep && *slave_sizep < size)
                size = *slave_sizep;
        assert(size > 0);
        while (xfer < size) {
-               size_t frames = snd_pcm_mmap_playback_xfer(slave, size - xfer);
+               snd_pcm_uframes_t frames = snd_pcm_mmap_playback_xfer(slave, size - xfer);
                
                snd_pcm_areas_copy(areas, offset, 
                                   snd_pcm_mmap_areas(slave), snd_pcm_mmap_offset(slave),
@@ -97,7 +110,7 @@ static ssize_t snd_pcm_copy_write_areas(snd_pcm_t *pcm,
                err = snd_pcm_mmap_forward(slave, frames);
                if (err < 0)
                        break;
-               assert((size_t)err == frames);
+               assert((snd_pcm_uframes_t)err == frames);
                offset += err;
                xfer += err;
                snd_pcm_mmap_hw_forward(pcm, err);
@@ -110,28 +123,28 @@ static ssize_t snd_pcm_copy_write_areas(snd_pcm_t *pcm,
        return err;
 }
 
-static ssize_t snd_pcm_copy_read_areas(snd_pcm_t *pcm,
+static snd_pcm_sframes_t snd_pcm_copy_read_areas(snd_pcm_t *pcm,
                                       const snd_pcm_channel_area_t *areas,
-                                      size_t offset,
-                                      size_t size,
-                                      size_t *slave_sizep)
+                                      snd_pcm_uframes_t offset,
+                                      snd_pcm_uframes_t size,
+                                      snd_pcm_uframes_t *slave_sizep)
 {
        snd_pcm_copy_t *copy = pcm->private;
        snd_pcm_t *slave = copy->plug.slave;
-       size_t xfer = 0;
-       ssize_t err = 0;
+       snd_pcm_uframes_t xfer = 0;
+       snd_pcm_sframes_t err = 0;
        if (slave_sizep && *slave_sizep < size)
                size = *slave_sizep;
        assert(size > 0);
        while (xfer < size) {
-               size_t frames = snd_pcm_mmap_capture_xfer(slave, size - xfer);
+               snd_pcm_uframes_t frames = snd_pcm_mmap_capture_xfer(slave, size - xfer);
                snd_pcm_areas_copy(snd_pcm_mmap_areas(slave), snd_pcm_mmap_offset(slave),
                                   areas, offset, 
                                   pcm->channels, frames, pcm->format);
                err = snd_pcm_mmap_forward(slave, frames);
                if (err < 0)
                        break;
-               assert((size_t)err == frames);
+               assert((snd_pcm_uframes_t)err == frames);
                offset += err;
                xfer += err;
                snd_pcm_mmap_hw_forward(pcm, err);
index 2f573d25f21436322843ae0793fa809bb58c2ae6..ca2f8c8092aa2c29fea5dff08486a92188ac32ca 100644 (file)
@@ -33,9 +33,9 @@ typedef struct {
        char *fname;
        int fd;
        int format;
-       size_t appl_ptr;
-       size_t file_ptr_bytes;
-       size_t wbuf_size;
+       snd_pcm_uframes_t appl_ptr;
+       snd_pcm_uframes_t file_ptr_bytes;
+       snd_pcm_uframes_t wbuf_size;
        size_t wbuf_size_bytes;
        size_t wbuf_used_bytes;
        char *wbuf;
@@ -48,7 +48,7 @@ static void snd_pcm_file_write_bytes(snd_pcm_t *pcm, size_t bytes)
        snd_pcm_file_t *file = pcm->private;
        assert(bytes <= file->wbuf_used_bytes);
        while (bytes > 0) {
-               ssize_t err;
+               snd_pcm_sframes_t err;
                size_t n = bytes;
                size_t cont = file->wbuf_size_bytes - file->file_ptr_bytes;
                if (n > cont)
@@ -63,20 +63,20 @@ static void snd_pcm_file_write_bytes(snd_pcm_t *pcm, size_t bytes)
                file->file_ptr_bytes += err;
                if (file->file_ptr_bytes == file->wbuf_size_bytes)
                        file->file_ptr_bytes = 0;
-               if ((size_t)err != n)
+               if ((snd_pcm_uframes_t)err != n)
                        break;
        }
 }
 
 static void snd_pcm_file_add_frames(snd_pcm_t *pcm, 
                                    const snd_pcm_channel_area_t *areas,
-                                   size_t offset, size_t frames)
+                                   snd_pcm_uframes_t offset, snd_pcm_uframes_t frames)
 {
        snd_pcm_file_t *file = pcm->private;
        while (frames > 0) {
-               size_t n = frames;
-               size_t cont = file->wbuf_size - file->appl_ptr;
-               size_t avail = file->wbuf_size - snd_pcm_bytes_to_frames(pcm, file->wbuf_used_bytes);
+               snd_pcm_uframes_t n = frames;
+               snd_pcm_uframes_t cont = file->wbuf_size - file->appl_ptr;
+               snd_pcm_uframes_t avail = file->wbuf_size - snd_pcm_bytes_to_frames(pcm, file->wbuf_used_bytes);
                if (n > cont)
                        n = cont;
                if (n > avail)
@@ -157,7 +157,7 @@ static int snd_pcm_file_state(snd_pcm_t *pcm)
        return snd_pcm_state(file->slave);
 }
 
-static int snd_pcm_file_delay(snd_pcm_t *pcm, ssize_t *delayp)
+static int snd_pcm_file_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp)
 {
        snd_pcm_file_t *file = pcm->private;
        return snd_pcm_delay(file->slave, delayp);
@@ -216,13 +216,13 @@ static int snd_pcm_file_pause(snd_pcm_t *pcm, int enable)
        return snd_pcm_pause(file->slave, enable);
 }
 
-static ssize_t snd_pcm_file_rewind(snd_pcm_t *pcm, size_t frames)
+static snd_pcm_sframes_t snd_pcm_file_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
 {
        snd_pcm_file_t *file = pcm->private;
-       ssize_t err = snd_pcm_rewind(file->slave, frames);
+       snd_pcm_sframes_t err = snd_pcm_rewind(file->slave, frames);
        if (err > 0) {
-               size_t n = snd_pcm_frames_to_bytes(pcm, frames);
-               ssize_t ptr;
+               snd_pcm_uframes_t n = snd_pcm_frames_to_bytes(pcm, frames);
+               snd_pcm_sframes_t ptr;
                assert(n >= file->wbuf_used_bytes);
                ptr = file->appl_ptr - err;
                if (ptr < 0)
@@ -232,11 +232,11 @@ static ssize_t snd_pcm_file_rewind(snd_pcm_t *pcm, size_t frames)
        return err;
 }
 
-static ssize_t snd_pcm_file_writei(snd_pcm_t *pcm, const void *buffer, size_t size)
+static snd_pcm_sframes_t snd_pcm_file_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size)
 {
        snd_pcm_file_t *file = pcm->private;
        snd_pcm_channel_area_t areas[pcm->channels];
-       ssize_t n = snd_pcm_writei(file->slave, buffer, size);
+       snd_pcm_sframes_t n = snd_pcm_writei(file->slave, buffer, size);
        if (n > 0) {
                snd_pcm_areas_from_buf(pcm, areas, (void*) buffer);
                snd_pcm_file_add_frames(pcm, areas, 0, n);
@@ -244,11 +244,11 @@ static ssize_t snd_pcm_file_writei(snd_pcm_t *pcm, const void *buffer, size_t si
        return n;
 }
 
-static ssize_t snd_pcm_file_writen(snd_pcm_t *pcm, void **bufs, size_t size)
+static snd_pcm_sframes_t snd_pcm_file_writen(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size)
 {
        snd_pcm_file_t *file = pcm->private;
        snd_pcm_channel_area_t areas[pcm->channels];
-       ssize_t n = snd_pcm_writen(file->slave, bufs, size);
+       snd_pcm_sframes_t n = snd_pcm_writen(file->slave, bufs, size);
        if (n > 0) {
                snd_pcm_areas_from_bufs(pcm, areas, bufs);
                snd_pcm_file_add_frames(pcm, areas, 0, n);
@@ -256,11 +256,11 @@ static ssize_t snd_pcm_file_writen(snd_pcm_t *pcm, void **bufs, size_t size)
        return n;
 }
 
-static ssize_t snd_pcm_file_readi(snd_pcm_t *pcm, void *buffer, size_t size)
+static snd_pcm_sframes_t snd_pcm_file_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size)
 {
        snd_pcm_file_t *file = pcm->private;
        snd_pcm_channel_area_t areas[pcm->channels];
-       ssize_t n = snd_pcm_readi(file->slave, buffer, size);
+       snd_pcm_sframes_t n = snd_pcm_readi(file->slave, buffer, size);
        if (n > 0) {
                snd_pcm_areas_from_buf(pcm, areas, buffer);
                snd_pcm_file_add_frames(pcm, areas, 0, n);
@@ -268,11 +268,11 @@ static ssize_t snd_pcm_file_readi(snd_pcm_t *pcm, void *buffer, size_t size)
        return n;
 }
 
-static ssize_t snd_pcm_file_readn(snd_pcm_t *pcm, void **bufs, size_t size)
+static snd_pcm_sframes_t snd_pcm_file_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size)
 {
        snd_pcm_file_t *file = pcm->private;
        snd_pcm_channel_area_t areas[pcm->channels];
-       ssize_t n = snd_pcm_writen(file->slave, bufs, size);
+       snd_pcm_sframes_t n = snd_pcm_writen(file->slave, bufs, size);
        if (n > 0) {
                snd_pcm_areas_from_bufs(pcm, areas, bufs);
                snd_pcm_file_add_frames(pcm, areas, 0, n);
@@ -280,17 +280,17 @@ static ssize_t snd_pcm_file_readn(snd_pcm_t *pcm, void **bufs, size_t size)
        return n;
 }
 
-static ssize_t snd_pcm_file_mmap_forward(snd_pcm_t *pcm, size_t size)
+static snd_pcm_sframes_t snd_pcm_file_mmap_forward(snd_pcm_t *pcm, snd_pcm_uframes_t size)
 {
        snd_pcm_file_t *file = pcm->private;
-       size_t ofs = snd_pcm_mmap_offset(pcm);
-       ssize_t n = snd_pcm_mmap_forward(file->slave, size);
-       size_t xfer = 0;
+       snd_pcm_uframes_t ofs = snd_pcm_mmap_offset(pcm);
+       snd_pcm_sframes_t n = snd_pcm_mmap_forward(file->slave, size);
+       snd_pcm_uframes_t xfer = 0;
        if (n <= 0)
                return n;
-       while (xfer < (size_t)n) {
-               size_t frames = size - xfer;
-               size_t cont = pcm->buffer_size - ofs;
+       while (xfer < (snd_pcm_uframes_t)n) {
+               snd_pcm_uframes_t frames = size - xfer;
+               snd_pcm_uframes_t cont = pcm->buffer_size - ofs;
                if (frames > cont)
                        frames = cont;
                snd_pcm_file_add_frames(pcm, snd_pcm_mmap_areas(file->slave), ofs, frames);
@@ -302,7 +302,7 @@ static ssize_t snd_pcm_file_mmap_forward(snd_pcm_t *pcm, size_t size)
        return n;
 }
 
-static ssize_t snd_pcm_file_avail_update(snd_pcm_t *pcm)
+static snd_pcm_sframes_t snd_pcm_file_avail_update(snd_pcm_t *pcm)
 {
        snd_pcm_file_t *file = pcm->private;
        return snd_pcm_avail_update(file->slave);
index ebe34b5e3e5dc0a30c14ecc7bb3a2fd8740b90f7..f64e037f865f03bc2c4498ca0da575a9c1d86e35 100644 (file)
@@ -153,10 +153,10 @@ static int snd_pcm_hw_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t * params)
        snd_pcm_hw_t *hw = pcm->private;
        int fd = hw->fd;
        if (params->start_mode == pcm->start_mode &&
-           params->ready_mode == pcm->ready_mode &&
            params->xrun_mode == pcm->xrun_mode &&
-           params->silence_mode == pcm->silence_mode &&
            params->tstamp_mode == pcm->tstamp_mode &&
+           params->period_step == pcm->period_step &&
+           params->sleep_min == pcm->sleep_min &&
            params->xfer_align == pcm->xfer_align &&
            params->silence_threshold == pcm->silence_threshold &&
            params->silence_size == pcm->silence_size) {
@@ -210,7 +210,7 @@ static int snd_pcm_hw_state(snd_pcm_t *pcm)
        return hw->mmap_status->state;
 }
 
-static int snd_pcm_hw_delay(snd_pcm_t *pcm, ssize_t *delayp)
+static int snd_pcm_hw_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp)
 {
        snd_pcm_hw_t *hw = pcm->private;
        int fd = hw->fd;
@@ -291,27 +291,20 @@ static int snd_pcm_hw_pause(snd_pcm_t *pcm, int enable)
        return 0;
 }
 
-static ssize_t snd_pcm_hw_rewind(snd_pcm_t *pcm, size_t frames)
+static snd_pcm_sframes_t snd_pcm_hw_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
 {
-       ssize_t hw_avail;
-       if (pcm->xrun_mode == SND_PCM_XRUN_ASAP) {
-               ssize_t d;
-               int err = snd_pcm_hw_delay(pcm, &d);
-               if (err < 0)
-                       return 0;
+       snd_pcm_hw_t *hw = pcm->private;
+       int fd = hw->fd;
+       if (ioctl(fd, SND_PCM_IOCTL_REWIND, &frames) < 0) {
+               SYSERR("SND_PCM_IOCTL_REWIND failed");
+               return -errno;
        }
-       hw_avail = snd_pcm_mmap_hw_avail(pcm);
-       if (hw_avail <= 0)
-               return 0;
-       if (frames > (size_t)hw_avail)
-               frames = hw_avail;
-       snd_pcm_mmap_appl_backward(pcm, frames);
-       return frames;
+       return 0;
 }
 
-static ssize_t snd_pcm_hw_writei(snd_pcm_t *pcm, const void *buffer, size_t size)
+static snd_pcm_sframes_t snd_pcm_hw_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size)
 {
-       ssize_t result;
+       snd_pcm_sframes_t result;
        snd_pcm_hw_t *hw = pcm->private;
        int fd = hw->fd;
        snd_xferi_t xferi;
@@ -323,9 +316,9 @@ static ssize_t snd_pcm_hw_writei(snd_pcm_t *pcm, const void *buffer, size_t size
        return xferi.result;
 }
 
-static ssize_t snd_pcm_hw_writen(snd_pcm_t *pcm, void **bufs, size_t size)
+static snd_pcm_sframes_t snd_pcm_hw_writen(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size)
 {
-       ssize_t result;
+       snd_pcm_sframes_t result;
        snd_pcm_hw_t *hw = pcm->private;
        int fd = hw->fd;
        snd_xfern_t xfern;
@@ -337,9 +330,9 @@ static ssize_t snd_pcm_hw_writen(snd_pcm_t *pcm, void **bufs, size_t size)
        return xfern.result;
 }
 
-static ssize_t snd_pcm_hw_readi(snd_pcm_t *pcm, void *buffer, size_t size)
+static snd_pcm_sframes_t snd_pcm_hw_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size)
 {
-       ssize_t result;
+       snd_pcm_sframes_t result;
        snd_pcm_hw_t *hw = pcm->private;
        int fd = hw->fd;
        snd_xferi_t xferi;
@@ -351,9 +344,9 @@ static ssize_t snd_pcm_hw_readi(snd_pcm_t *pcm, void *buffer, size_t size)
        return xferi.result;
 }
 
-ssize_t snd_pcm_hw_readn(snd_pcm_t *pcm, void **bufs, size_t size)
+snd_pcm_sframes_t snd_pcm_hw_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size)
 {
-       ssize_t result;
+       snd_pcm_sframes_t result;
        snd_pcm_hw_t *hw = pcm->private;
        int fd = hw->fd;
        snd_xfern_t xfern;
@@ -419,7 +412,7 @@ static int snd_pcm_hw_mmap(snd_pcm_t *pcm)
 {
        snd_pcm_hw_t *hw = pcm->private;
        if (!(pcm->info & SND_PCM_INFO_MMAP)) {
-               size_t size = snd_pcm_frames_to_bytes(pcm, pcm->buffer_size);
+               snd_pcm_uframes_t size = snd_pcm_frames_to_bytes(pcm, pcm->buffer_size);
                int id = shmget(IPC_PRIVATE, size, 0666);
                if (id < 0) {
                        SYSERR("shmget failed");
@@ -455,7 +448,7 @@ static int snd_pcm_hw_close(snd_pcm_t *pcm)
        return 0;
 }
 
-static ssize_t snd_pcm_hw_mmap_forward(snd_pcm_t *pcm, size_t size)
+static snd_pcm_sframes_t snd_pcm_hw_mmap_forward(snd_pcm_t *pcm, snd_pcm_uframes_t size)
 {
        if (!(pcm->info & SND_PCM_INFO_MMAP) && 
            pcm->stream == SND_PCM_STREAM_PLAYBACK)
@@ -464,17 +457,19 @@ static ssize_t snd_pcm_hw_mmap_forward(snd_pcm_t *pcm, size_t size)
        return size;
 }
 
-static ssize_t snd_pcm_hw_avail_update(snd_pcm_t *pcm)
+static snd_pcm_sframes_t snd_pcm_hw_avail_update(snd_pcm_t *pcm)
 {
-       size_t avail;
-       ssize_t err;
+       snd_pcm_uframes_t avail;
+       snd_pcm_sframes_t err;
+#if 0
        if (pcm->ready_mode == SND_PCM_READY_ASAP ||
            pcm->xrun_mode == SND_PCM_XRUN_ASAP) {
-               ssize_t d;
+               snd_pcm_sframes_t d;
                int err = snd_pcm_hw_delay(pcm, &d);
                if (err < 0)
                        return err;
        }
+#endif
        if (pcm->stream == SND_PCM_STREAM_PLAYBACK) {
                avail = snd_pcm_mmap_playback_avail(pcm);
        } else {
@@ -484,7 +479,7 @@ static ssize_t snd_pcm_hw_avail_update(snd_pcm_t *pcm)
                        err = snd_pcm_read_mmap(pcm, avail);
                        if (err < 0)
                                return err;
-                       assert((size_t)err == avail);
+                       assert((snd_pcm_uframes_t)err == avail);
                        return err;
                }
        }
@@ -605,7 +600,7 @@ int snd_pcm_hw_open_subdevice(snd_pcm_t **pcmp, int card, int device, int subdev
                        ret = -errno;
                        goto _err;
                }
-               if (info.subdevice != subdevice) {
+               if (info.subdevice != (unsigned int) subdevice) {
                        close(fd);
                        goto __again;
                }
index 560c24ed552dd7ebb38091dc15c470617d796727..4c30e9e99fea678252484134b53e068eb36d88c6 100644 (file)
@@ -30,9 +30,9 @@ typedef struct {
        int sformat;
 } snd_pcm_linear_t;
 
-static void linear_transfer(const snd_pcm_channel_area_t *src_areas, size_t src_offset,
-                           const snd_pcm_channel_area_t *dst_areas, size_t dst_offset,
-                           size_t channels, size_t frames, int convidx)
+static void linear_transfer(const snd_pcm_channel_area_t *src_areas, snd_pcm_uframes_t src_offset,
+                           const snd_pcm_channel_area_t *dst_areas, snd_pcm_uframes_t dst_offset,
+                           unsigned int channels, snd_pcm_uframes_t frames, int convidx)
 {
 #define CONV_LABELS
 #include "plugin_ops.h"
@@ -43,7 +43,7 @@ static void linear_transfer(const snd_pcm_channel_area_t *src_areas, size_t src_
                char *src;
                char *dst;
                int src_step, dst_step;
-               size_t frames1;
+               snd_pcm_uframes_t frames1;
                const snd_pcm_channel_area_t *src_area = &src_areas[channel];
                const snd_pcm_channel_area_t *dst_area = &dst_areas[channel];
 #if 0
@@ -77,6 +77,7 @@ static int snd_pcm_linear_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
        snd_pcm_linear_t *linear = pcm->private;
        snd_pcm_t *slave = linear->plug.slave;
        int err;
+       unsigned int cmask, lcmask;
        snd_pcm_hw_params_t sparams;
        mask_t *access_mask = alloca(mask_sizeof());
        mask_t *format_mask = alloca(mask_sizeof());
@@ -84,35 +85,41 @@ static int snd_pcm_linear_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
        mask_load(access_mask, SND_PCM_ACCBIT_PLUGIN);
        mask_load(format_mask, SND_PCM_FMTBIT_LINEAR);
        mask_load(saccess_mask, SND_PCM_ACCBIT_MMAP);
-       err = _snd_pcm_hw_param_mask(params, 1, SND_PCM_HW_PARAM_ACCESS,
+       cmask = params->cmask;
+       params->cmask = 0;
+       err = _snd_pcm_hw_param_mask(params, SND_PCM_HW_PARAM_ACCESS,
                                      access_mask);
        if (err < 0)
                return err;
-       err = _snd_pcm_hw_param_mask(params, 1, SND_PCM_HW_PARAM_FORMAT,
+       err = _snd_pcm_hw_param_mask(params, SND_PCM_HW_PARAM_FORMAT,
                                      format_mask);
        if (err < 0)
                return err;
-       err = _snd_pcm_hw_param_set(params, 1, SND_PCM_HW_PARAM_SUBFORMAT,
-                                    SND_PCM_SUBFORMAT_STD);
+       err = _snd_pcm_hw_param_set(params, SND_PCM_HW_PARAM_SUBFORMAT,
+                                   SND_PCM_SUBFORMAT_STD, 0);
        if (err < 0)
                return err;
+       lcmask = params->cmask;
+       params->cmask |= cmask;
 
        _snd_pcm_hw_params_any(&sparams);
-       _snd_pcm_hw_param_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
+       _snd_pcm_hw_param_mask(&sparams, SND_PCM_HW_PARAM_ACCESS,
                                saccess_mask);
-       _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_FORMAT,
-                              linear->sformat);
-       _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_SUBFORMAT,
-                              SND_PCM_SUBFORMAT_STD);
+       _snd_pcm_hw_param_set(&sparams, SND_PCM_HW_PARAM_FORMAT,
+                             linear->sformat, 0);
+       _snd_pcm_hw_param_set(&sparams, SND_PCM_HW_PARAM_SUBFORMAT,
+                             SND_PCM_SUBFORMAT_STD, 0);
        err = snd_pcm_hw_refine2(params, &sparams,
-                                snd_pcm_hw_refine, slave,
+                                snd_pcm_generic_hw_link, slave,
                                 SND_PCM_HW_PARBIT_CHANNELS |
                                 SND_PCM_HW_PARBIT_RATE |
-                                SND_PCM_HW_PARBIT_FRAGMENT_SIZE |
+                                SND_PCM_HW_PARBIT_PERIOD_SIZE |
                                 SND_PCM_HW_PARBIT_BUFFER_SIZE |
-                                SND_PCM_HW_PARBIT_FRAGMENTS |
-                                SND_PCM_HW_PARBIT_FRAGMENT_LENGTH |
-                                SND_PCM_HW_PARBIT_BUFFER_LENGTH);
+                                SND_PCM_HW_PARBIT_PERIODS |
+                                SND_PCM_HW_PARBIT_PERIOD_TIME |
+                                SND_PCM_HW_PARBIT_BUFFER_TIME |
+                                SND_PCM_HW_PARBIT_TICK_TIME);
+       params->cmask |= lcmask;
        if (err < 0)
                return err;
        params->info &= ~(SND_PCM_INFO_MMAP | SND_PCM_INFO_MMAP_VALID);
@@ -124,60 +131,68 @@ static int snd_pcm_linear_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
        snd_pcm_linear_t *linear = pcm->private;
        snd_pcm_t *slave = linear->plug.slave;
        int err;
+       unsigned int links;
        snd_pcm_hw_params_t sparams;
        mask_t *saccess_mask = alloca(mask_sizeof());
        mask_load(saccess_mask, SND_PCM_ACCBIT_MMAP);
 
        _snd_pcm_hw_params_any(&sparams);
-       _snd_pcm_hw_param_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
+       _snd_pcm_hw_param_mask(&sparams, SND_PCM_HW_PARAM_ACCESS,
                                saccess_mask);
-       _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_FORMAT,
-                              linear->sformat);
-       _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_SUBFORMAT,
-                              SND_PCM_SUBFORMAT_STD);
-       err = snd_pcm_hw_params2(params, &sparams,
-                                snd_pcm_hw_params, slave,
-                                SND_PCM_HW_PARBIT_CHANNELS |
-                                SND_PCM_HW_PARBIT_RATE |
-                                SND_PCM_HW_PARBIT_FRAGMENT_SIZE |
-                                SND_PCM_HW_PARBIT_BUFFER_SIZE |
-                                SND_PCM_HW_PARBIT_FRAGMENTS |
-                                SND_PCM_HW_PARBIT_FRAGMENT_LENGTH |
-                                SND_PCM_HW_PARBIT_BUFFER_LENGTH);
+       _snd_pcm_hw_param_set(&sparams, SND_PCM_HW_PARAM_FORMAT,
+                             linear->sformat, 0);
+       _snd_pcm_hw_param_set(&sparams, SND_PCM_HW_PARAM_SUBFORMAT,
+                              SND_PCM_SUBFORMAT_STD, 0);
+       links = SND_PCM_HW_PARBIT_CHANNELS |
+               SND_PCM_HW_PARBIT_RATE |
+               SND_PCM_HW_PARBIT_PERIOD_SIZE |
+               SND_PCM_HW_PARBIT_BUFFER_SIZE |
+               SND_PCM_HW_PARBIT_PERIODS |
+               SND_PCM_HW_PARBIT_PERIOD_TIME |
+               SND_PCM_HW_PARBIT_BUFFER_TIME |
+               SND_PCM_HW_PARBIT_TICK_TIME;
+       err = snd_pcm_hw_params_refine(&sparams, links, params);
+       assert(err >= 0);
+       err = _snd_pcm_hw_refine(&sparams);
+       assert(err >= 0);
+       err = snd_pcm_hw_params(slave, &sparams);
+       params->cmask = 0;
+       sparams.cmask = ~0U;
+       snd_pcm_hw_params_refine(params, links, &sparams);
        if (err < 0)
                return err;
        params->info &= ~(SND_PCM_INFO_MMAP | SND_PCM_INFO_MMAP_VALID);
        if (pcm->stream == SND_PCM_STREAM_PLAYBACK)
-               linear->conv_idx = conv_index(snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FORMAT),
+               linear->conv_idx = conv_index(snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FORMAT, 0),
                                              linear->sformat);
        else
                linear->conv_idx = conv_index(linear->sformat,
-                                             snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FORMAT));
+                                             snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FORMAT, 0));
        return 0;
 }
 
-static ssize_t snd_pcm_linear_write_areas(snd_pcm_t *pcm,
+static snd_pcm_sframes_t snd_pcm_linear_write_areas(snd_pcm_t *pcm,
                                          const snd_pcm_channel_area_t *areas,
-                                         size_t offset,
-                                         size_t size,
-                                         size_t *slave_sizep)
+                                         snd_pcm_uframes_t offset,
+                                         snd_pcm_uframes_t size,
+                                         snd_pcm_uframes_t *slave_sizep)
 {
        snd_pcm_linear_t *linear = pcm->private;
        snd_pcm_t *slave = linear->plug.slave;
-       size_t xfer = 0;
-       ssize_t err = 0;
+       snd_pcm_uframes_t xfer = 0;
+       snd_pcm_sframes_t err = 0;
        if (slave_sizep && *slave_sizep < size)
                size = *slave_sizep;
        assert(size > 0);
        while (xfer < size) {
-               size_t frames = snd_pcm_mmap_playback_xfer(slave, size - xfer);
+               snd_pcm_uframes_t frames = snd_pcm_mmap_playback_xfer(slave, size - xfer);
                linear_transfer(areas, offset, 
                                snd_pcm_mmap_areas(slave), snd_pcm_mmap_offset(slave),
                                pcm->channels, frames, linear->conv_idx);
                err = snd_pcm_mmap_forward(slave, frames);
                if (err < 0)
                        break;
-               assert((size_t)err == frames);
+               assert((snd_pcm_uframes_t)err == frames);
                offset += err;
                xfer += err;
                snd_pcm_mmap_hw_forward(pcm, err);
@@ -190,28 +205,28 @@ static ssize_t snd_pcm_linear_write_areas(snd_pcm_t *pcm,
        return err;
 }
 
-static ssize_t snd_pcm_linear_read_areas(snd_pcm_t *pcm,
+static snd_pcm_sframes_t snd_pcm_linear_read_areas(snd_pcm_t *pcm,
                                         const snd_pcm_channel_area_t *areas,
-                                        size_t offset,
-                                        size_t size,
-                                        size_t *slave_sizep)
+                                        snd_pcm_uframes_t offset,
+                                        snd_pcm_uframes_t size,
+                                        snd_pcm_uframes_t *slave_sizep)
 {
        snd_pcm_linear_t *linear = pcm->private;
        snd_pcm_t *slave = linear->plug.slave;
-       size_t xfer = 0;
-       ssize_t err = 0;
+       snd_pcm_uframes_t xfer = 0;
+       snd_pcm_sframes_t err = 0;
        if (slave_sizep && *slave_sizep < size)
                size = *slave_sizep;
        assert(size > 0);
        while (xfer < size) {
-               size_t frames = snd_pcm_mmap_capture_xfer(slave, size - xfer);
+               snd_pcm_uframes_t frames = snd_pcm_mmap_capture_xfer(slave, size - xfer);
                linear_transfer(snd_pcm_mmap_areas(slave), snd_pcm_mmap_offset(slave),
                                areas, offset, 
                                pcm->channels, frames, linear->conv_idx);
                err = snd_pcm_mmap_forward(slave, frames);
                if (err < 0)
                        break;
-               assert((size_t)err == frames);
+               assert((snd_pcm_uframes_t)err == frames);
                offset += err;
                xfer += err;
                snd_pcm_mmap_hw_forward(pcm, err);
index 7fba5fd3451d1243f8a11d026bbcf488ab0f93b8..c465d96c4222922a7dd937dc970e225700639eef 100644 (file)
@@ -71,14 +71,14 @@ typedef struct {
        int (*drain)(snd_pcm_t *pcm);
        int (*pause)(snd_pcm_t *pcm, int enable);
        int (*state)(snd_pcm_t *pcm);
-       int (*delay)(snd_pcm_t *pcm, ssize_t *delayp);
-       ssize_t (*rewind)(snd_pcm_t *pcm, size_t frames);
-       ssize_t (*writei)(snd_pcm_t *pcm, const void *buffer, size_t size);
-       ssize_t (*writen)(snd_pcm_t *pcm, void **bufs, size_t size);
-       ssize_t (*readi)(snd_pcm_t *pcm, void *buffer, size_t size);
-       ssize_t (*readn)(snd_pcm_t *pcm, void **bufs, size_t size);
-       ssize_t (*avail_update)(snd_pcm_t *pcm);
-       ssize_t (*mmap_forward)(snd_pcm_t *pcm, size_t size);
+       int (*delay)(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp);
+       snd_pcm_sframes_t (*rewind)(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
+       snd_pcm_sframes_t (*writei)(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size);
+       snd_pcm_sframes_t (*writen)(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size);
+       snd_pcm_sframes_t (*readi)(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size);
+       snd_pcm_sframes_t (*readn)(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size);
+       snd_pcm_sframes_t (*avail_update)(snd_pcm_t *pcm);
+       snd_pcm_sframes_t (*mmap_forward)(snd_pcm_t *pcm, snd_pcm_uframes_t size);
 } snd_pcm_fast_ops_t;
 
 struct _snd_pcm {
@@ -93,30 +93,31 @@ struct _snd_pcm {
        unsigned int subformat;         /* subformat */
        unsigned int channels;          /* channels */
        unsigned int rate;              /* rate in Hz */
-       size_t fragment_size;           /* fragment size */
-       unsigned int fragments;         /* fragments */
-       unsigned int start_mode;        /* start mode */
-       unsigned int xrun_mode;         /* xrun detection mode */
-       unsigned int ready_mode;        /* ready detection mode */
-       unsigned int tstamp_mode;       /* timestamp mode */
-       size_t avail_min;               /* min avail frames for wakeup */
-       unsigned int silence_mode;      /* Silence filling mode */
-       size_t silence_threshold;       /* Silence filling happens when
+       snd_pcm_uframes_t period_size;
+       unsigned int period_time;       /* period duration */
+       unsigned int tick_time;
+       snd_pcm_start_t start_mode;     /* start mode */
+       snd_pcm_xrun_t xrun_mode;       /* xrun detection mode */
+       snd_pcm_tstamp_t tstamp_mode;   /* timestamp mode */
+       unsigned int period_step;
+       unsigned int sleep_min;
+       snd_pcm_uframes_t avail_min;    /* min avail frames for wakeup */
+       snd_pcm_uframes_t silence_threshold;    /* Silence filling happens when
                                           noise is nearest than this */
-       size_t silence_size;            /* Silence filling size */
-       size_t xfer_align;              /* xfer size need to be a multiple */
-       size_t boundary;                /* pointers wrap point */
+       snd_pcm_uframes_t silence_size; /* Silence filling size */
+       snd_pcm_uframes_t xfer_align;   /* xfer size need to be a multiple */
+       snd_pcm_uframes_t boundary;     /* pointers wrap point */
        unsigned int info;              /* Info for returned setup */
        unsigned int msbits;            /* used most significant bits */
        unsigned int rate_num;          /* rate numerator */
        unsigned int rate_den;          /* rate denominator */
-       size_t fifo_size;               /* chip FIFO size in frames */
-       size_t buffer_size;
-       size_t bits_per_sample;
-       size_t bits_per_frame;
-       size_t *appl_ptr;
-       size_t min_align;
-       volatile size_t *hw_ptr;
+       snd_pcm_uframes_t fifo_size;    /* chip FIFO size in frames */
+       snd_pcm_uframes_t buffer_size;
+       unsigned int bits_per_sample;
+       unsigned int bits_per_frame;
+       snd_pcm_uframes_t *appl_ptr;
+       snd_pcm_uframes_t min_align;
+       volatile snd_pcm_uframes_t *hw_ptr;
        int mmap_rw;
        snd_pcm_channel_info_t *mmap_channels;
        snd_pcm_channel_area_t *running_areas;
@@ -142,52 +143,52 @@ void snd_pcm_areas_from_bufs(snd_pcm_t *pcm, snd_pcm_channel_area_t *areas, void
 int snd_pcm_mmap(snd_pcm_t *pcm);
 int snd_pcm_munmap(snd_pcm_t *pcm);
 int snd_pcm_mmap_ready(snd_pcm_t *pcm);
-ssize_t snd_pcm_mmap_appl_ptr(snd_pcm_t *pcm, off_t offset);
-void snd_pcm_mmap_appl_backward(snd_pcm_t *pcm, size_t frames);
-void snd_pcm_mmap_appl_forward(snd_pcm_t *pcm, size_t frames);
-void snd_pcm_mmap_hw_backward(snd_pcm_t *pcm, size_t frames);
-void snd_pcm_mmap_hw_forward(snd_pcm_t *pcm, size_t frames);
-size_t snd_pcm_mmap_hw_offset(snd_pcm_t *pcm);
-size_t snd_pcm_mmap_playback_xfer(snd_pcm_t *pcm, size_t frames);
-size_t snd_pcm_mmap_capture_xfer(snd_pcm_t *pcm, size_t frames);
-
-typedef ssize_t (*snd_pcm_xfer_areas_func_t)(snd_pcm_t *pcm, 
+snd_pcm_sframes_t snd_pcm_mmap_appl_ptr(snd_pcm_t *pcm, off_t offset);
+void snd_pcm_mmap_appl_backward(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
+void snd_pcm_mmap_appl_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
+void snd_pcm_mmap_hw_backward(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
+void snd_pcm_mmap_hw_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
+snd_pcm_uframes_t snd_pcm_mmap_hw_offset(snd_pcm_t *pcm);
+snd_pcm_uframes_t snd_pcm_mmap_playback_xfer(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
+snd_pcm_uframes_t snd_pcm_mmap_capture_xfer(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
+
+typedef snd_pcm_sframes_t (*snd_pcm_xfer_areas_func_t)(snd_pcm_t *pcm, 
                                             const snd_pcm_channel_area_t *areas,
-                                            size_t offset, size_t size,
-                                            size_t *slave_sizep);
+                                            snd_pcm_uframes_t offset, snd_pcm_uframes_t size,
+                                            snd_pcm_uframes_t *slave_sizep);
 
-ssize_t snd_pcm_read_areas(snd_pcm_t *pcm, const snd_pcm_channel_area_t *areas,
-                          size_t offset, size_t size,
+snd_pcm_sframes_t snd_pcm_read_areas(snd_pcm_t *pcm, const snd_pcm_channel_area_t *areas,
+                          snd_pcm_uframes_t offset, snd_pcm_uframes_t size,
                           snd_pcm_xfer_areas_func_t func);
-ssize_t snd_pcm_write_areas(snd_pcm_t *pcm, const snd_pcm_channel_area_t *areas,
-                           size_t offset, size_t size,
+snd_pcm_sframes_t snd_pcm_write_areas(snd_pcm_t *pcm, const snd_pcm_channel_area_t *areas,
+                           snd_pcm_uframes_t offset, snd_pcm_uframes_t size,
                            snd_pcm_xfer_areas_func_t func);
-ssize_t snd_pcm_read_mmap(snd_pcm_t *pcm, size_t size);
-ssize_t snd_pcm_write_mmap(snd_pcm_t *pcm, size_t size);
+snd_pcm_sframes_t snd_pcm_read_mmap(snd_pcm_t *pcm, snd_pcm_uframes_t size);
+snd_pcm_sframes_t snd_pcm_write_mmap(snd_pcm_t *pcm, snd_pcm_uframes_t size);
 int snd_pcm_channel_info(snd_pcm_t *pcm, snd_pcm_channel_info_t *info);
 int snd_pcm_channel_info_shm(snd_pcm_t *pcm, snd_pcm_channel_info_t *info, int shmid);
 
-static inline size_t snd_pcm_mmap_playback_avail(snd_pcm_t *pcm)
+static inline snd_pcm_uframes_t snd_pcm_mmap_playback_avail(snd_pcm_t *pcm)
 {
-       ssize_t avail;
+       snd_pcm_sframes_t avail;
        avail = *pcm->hw_ptr + pcm->buffer_size - *pcm->appl_ptr;
        if (avail < 0)
                avail += pcm->boundary;
        return avail;
 }
 
-static inline size_t snd_pcm_mmap_capture_avail(snd_pcm_t *pcm)
+static inline snd_pcm_uframes_t snd_pcm_mmap_capture_avail(snd_pcm_t *pcm)
 {
-       ssize_t avail;
+       snd_pcm_sframes_t avail;
        avail = *pcm->hw_ptr - *pcm->appl_ptr;
        if (avail < 0)
                avail += pcm->boundary;
        return avail;
 }
 
-static inline size_t snd_pcm_mmap_avail(snd_pcm_t *pcm)
+static inline snd_pcm_uframes_t snd_pcm_mmap_avail(snd_pcm_t *pcm)
 {
-       ssize_t avail;
+       snd_pcm_sframes_t avail;
        avail = *pcm->hw_ptr - *pcm->appl_ptr;
        if (pcm->stream == SND_PCM_STREAM_PLAYBACK)
                avail += pcm->buffer_size;
@@ -196,27 +197,19 @@ static inline size_t snd_pcm_mmap_avail(snd_pcm_t *pcm)
        return avail;
 }
 
-static inline ssize_t snd_pcm_mmap_playback_hw_avail(snd_pcm_t *pcm)
+static inline snd_pcm_sframes_t snd_pcm_mmap_playback_hw_avail(snd_pcm_t *pcm)
 {
-       ssize_t avail;
-       avail = *pcm->hw_ptr + pcm->buffer_size - *pcm->appl_ptr;
-       if (avail < 0)
-               avail += pcm->boundary;
-       return pcm->buffer_size - avail;
+       return pcm->buffer_size - snd_pcm_mmap_playback_avail(pcm);
 }
 
-static inline ssize_t snd_pcm_mmap_capture_hw_avail(snd_pcm_t *pcm)
+static inline snd_pcm_sframes_t snd_pcm_mmap_capture_hw_avail(snd_pcm_t *pcm)
 {
-       ssize_t avail;
-       avail = *pcm->hw_ptr - *pcm->appl_ptr;
-       if (avail < 0)
-               avail += pcm->boundary;
-       return pcm->buffer_size - avail;
+       return pcm->buffer_size - snd_pcm_mmap_capture_avail(pcm);
 }
 
-static inline ssize_t snd_pcm_mmap_hw_avail(snd_pcm_t *pcm)
+static inline snd_pcm_sframes_t snd_pcm_mmap_hw_avail(snd_pcm_t *pcm)
 {
-       ssize_t avail;
+       snd_pcm_sframes_t avail;
        avail = *pcm->hw_ptr - *pcm->appl_ptr;
        if (pcm->stream == SND_PCM_STREAM_PLAYBACK)
                avail += pcm->buffer_size;
@@ -228,7 +221,7 @@ static inline ssize_t snd_pcm_mmap_hw_avail(snd_pcm_t *pcm)
 #define snd_pcm_mmap_playback_delay snd_pcm_mmap_playback_hw_avail
 #define snd_pcm_mmap_capture_delay snd_pcm_mmap_capture_avail
 
-static inline ssize_t snd_pcm_mmap_delay(snd_pcm_t *pcm)
+static inline snd_pcm_sframes_t snd_pcm_mmap_delay(snd_pcm_t *pcm)
 {
        if (pcm->stream == SND_PCM_STREAM_PLAYBACK)
                return snd_pcm_mmap_playback_delay(pcm);
@@ -236,35 +229,35 @@ static inline ssize_t snd_pcm_mmap_delay(snd_pcm_t *pcm)
                return snd_pcm_mmap_capture_delay(pcm);
 }
 
-static inline void *snd_pcm_channel_area_addr(const snd_pcm_channel_area_t *area, size_t offset)
+static inline void *snd_pcm_channel_area_addr(const snd_pcm_channel_area_t *area, snd_pcm_uframes_t offset)
 {
-       size_t bitofs = area->first + area->step * offset;
+       unsigned int bitofs = area->first + area->step * offset;
        assert(bitofs % 8 == 0);
        return area->addr + bitofs / 8;
 }
 
-static inline size_t snd_pcm_channel_area_step(const snd_pcm_channel_area_t *area)
+static inline unsigned int snd_pcm_channel_area_step(const snd_pcm_channel_area_t *area)
 {
        assert(area->step % 8 == 0);
        return area->step / 8;
 }
 
-static inline ssize_t _snd_pcm_writei(snd_pcm_t *pcm, const void *buffer, size_t size)
+static inline snd_pcm_sframes_t _snd_pcm_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size)
 {
        return pcm->fast_ops->writei(pcm->fast_op_arg, buffer, size);
 }
 
-static inline ssize_t _snd_pcm_writen(snd_pcm_t *pcm, void **bufs, size_t size)
+static inline snd_pcm_sframes_t _snd_pcm_writen(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size)
 {
        return pcm->fast_ops->writen(pcm->fast_op_arg, bufs, size);
 }
 
-static inline ssize_t _snd_pcm_readi(snd_pcm_t *pcm, void *buffer, size_t size)
+static inline snd_pcm_sframes_t _snd_pcm_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size)
 {
        return pcm->fast_ops->readi(pcm->fast_op_arg, buffer, size);
 }
 
-static inline ssize_t _snd_pcm_readn(snd_pcm_t *pcm, void **bufs, size_t size)
+static inline snd_pcm_sframes_t _snd_pcm_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size)
 {
        return pcm->fast_ops->readn(pcm->fast_op_arg, bufs, size);
 }
@@ -308,45 +301,71 @@ static inline int muldiv_near(int a, int b, int c)
 
 int _snd_pcm_hw_refine(snd_pcm_hw_params_t *params);
 void _snd_pcm_hw_params_any(snd_pcm_hw_params_t *params);
-int _snd_pcm_hw_param_mask(snd_pcm_hw_params_t *params, int hw,
+int _snd_pcm_hw_param_refine_interval(snd_pcm_hw_params_t *params,
+                                     snd_pcm_hw_param_t var,
+                                     const interval_t *val);
+int _snd_pcm_hw_param_mask(snd_pcm_hw_params_t *params,
                            unsigned int var, const mask_t *mask);
-int _snd_pcm_hw_param_first(snd_pcm_hw_params_t *params, int hw,
-                            unsigned int var);
-int _snd_pcm_hw_param_last(snd_pcm_hw_params_t *params, int hw,
+int _snd_pcm_hw_param_first(snd_pcm_hw_params_t *params,
                            unsigned int var);
-int _snd_pcm_hw_param_set(snd_pcm_hw_params_t *params, int hw,
-                          unsigned int var, unsigned int val);
-int _snd_pcm_hw_param_min(snd_pcm_hw_params_t *params, int hw,
-                          unsigned int var, unsigned int val);
-int _snd_pcm_hw_param_max(snd_pcm_hw_params_t *params, int hw,
-                          unsigned int var, unsigned int val);
+int _snd_pcm_hw_param_last(snd_pcm_hw_params_t *params,
+                          unsigned int var);
+int _snd_pcm_hw_param_set(snd_pcm_hw_params_t *params,
+                          unsigned int var, unsigned int val, int dir);
+int _snd_pcm_hw_param_min(snd_pcm_hw_params_t *params,
+                          unsigned int var, unsigned int val, int dir);
+int _snd_pcm_hw_param_max(snd_pcm_hw_params_t *params,
+                          unsigned int var, unsigned int val, int dir);
+int snd_pcm_hw_param_refine(snd_pcm_hw_params_t *params,
+                           snd_pcm_hw_param_t var,
+                           const snd_pcm_hw_params_t *src);
+int snd_pcm_hw_params_refine(snd_pcm_hw_params_t *params,
+                            unsigned int vars,
+                            const snd_pcm_hw_params_t *src);
+int snd_pcm_generic_hw_link(snd_pcm_hw_params_t *params,
+                           snd_pcm_hw_params_t *sparams,
+                           snd_pcm_t *slave,
+                           unsigned long links);
 int snd_pcm_hw_refine2(snd_pcm_hw_params_t *params,
                       snd_pcm_hw_params_t *sparams,
-                      int (*func)(snd_pcm_t *slave,
-                                  snd_pcm_hw_params_t *params),
+                      int (*func)(snd_pcm_hw_params_t *params,
+                                  snd_pcm_hw_params_t *sparams,
+                                  snd_pcm_t *slave,
+                                  unsigned long private),
                       snd_pcm_t *slave,
-                      unsigned int links);
+                      unsigned long private);
 int snd_pcm_hw_params2(snd_pcm_hw_params_t *params,
                       snd_pcm_hw_params_t *sparams,
                       int (*func)(snd_pcm_t *slave, 
                                   snd_pcm_hw_params_t *sparams),
                       snd_pcm_t *slave,
                       unsigned int links);
+void snd_pcm_hw_param_near_copy(snd_pcm_t *pcm,
+                               snd_pcm_hw_params_t *params,
+                               snd_pcm_hw_param_t var,
+                               const snd_pcm_hw_params_t *src);
+int snd_pcm_hw_param_always_eq(const snd_pcm_hw_params_t *params,
+                              snd_pcm_hw_param_t var,
+                              const snd_pcm_hw_params_t *params1);
+int snd_pcm_hw_param_never_eq(const snd_pcm_hw_params_t *params,
+                             snd_pcm_hw_param_t var,
+                             const snd_pcm_hw_params_t *params1);
 
 #define SND_PCM_HW_PARBIT_ACCESS       (1 << SND_PCM_HW_PARAM_ACCESS)
 #define SND_PCM_HW_PARBIT_FORMAT       (1 << SND_PCM_HW_PARAM_FORMAT)
 #define SND_PCM_HW_PARBIT_SUBFORMAT    (1 << SND_PCM_HW_PARAM_SUBFORMAT)
 #define SND_PCM_HW_PARBIT_CHANNELS     (1 << SND_PCM_HW_PARAM_CHANNELS)
 #define SND_PCM_HW_PARBIT_RATE         (1 << SND_PCM_HW_PARAM_RATE)
-#define SND_PCM_HW_PARBIT_FRAGMENT_LENGTH (1 << SND_PCM_HW_PARAM_FRAGMENT_LENGTH)
-#define SND_PCM_HW_PARBIT_FRAGMENT_SIZE        (1 << SND_PCM_HW_PARAM_FRAGMENT_SIZE)
-#define SND_PCM_HW_PARBIT_FRAGMENTS    (1 << SND_PCM_HW_PARAM_FRAGMENTS)
-#define SND_PCM_HW_PARBIT_BUFFER_LENGTH        (1 << SND_PCM_HW_PARAM_BUFFER_LENGTH)
+#define SND_PCM_HW_PARBIT_PERIOD_TIME  (1 << SND_PCM_HW_PARAM_PERIOD_TIME)
+#define SND_PCM_HW_PARBIT_PERIOD_SIZE  (1 << SND_PCM_HW_PARAM_PERIOD_SIZE)
+#define SND_PCM_HW_PARBIT_PERIODS      (1 << SND_PCM_HW_PARAM_PERIODS)
+#define SND_PCM_HW_PARBIT_BUFFER_TIME  (1 << SND_PCM_HW_PARAM_BUFFER_TIME)
 #define SND_PCM_HW_PARBIT_BUFFER_SIZE  (1 << SND_PCM_HW_PARAM_BUFFER_SIZE)
 #define SND_PCM_HW_PARBIT_SAMPLE_BITS  (1 << SND_PCM_HW_PARAM_SAMPLE_BITS)
 #define SND_PCM_HW_PARBIT_FRAME_BITS   (1 << SND_PCM_HW_PARAM_FRAME_BITS)
-#define SND_PCM_HW_PARBIT_FRAGMENT_BYTES (1 << SND_PCM_HW_PARAM_FRAGMENT_BYTES)
+#define SND_PCM_HW_PARBIT_PERIOD_BYTES (1 << SND_PCM_HW_PARAM_PERIOD_BYTES)
 #define SND_PCM_HW_PARBIT_BUFFER_BYTES (1 << SND_PCM_HW_PARAM_BUFFER_BYTES)
+#define SND_PCM_HW_PARBIT_TICK_TIME    (1 << SND_PCM_HW_PARAM_TICK_TIME)
 
 
 #define SND_PCM_ACCBIT_MMAP ((1 << SND_PCM_ACCESS_MMAP_INTERLEAVED) | \
index 5d0f0c2065236f1b46f3bf93e3950f6982be9f18..fa7b7e7be58ebeb8b0f9705e0d4c3458bd32d6e5 100644 (file)
@@ -360,14 +360,14 @@ 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 samples)
+int snd_pcm_format_set_silence(int format, void *data, unsigned int samples)
 {
        if (samples == 0)
                return 0;
        switch (snd_pcm_format_width(format)) {
        case 4: {
                u_int8_t silence = snd_pcm_format_silence_64(format);
-               size_t samples1;
+               unsigned int samples1;
                if (samples % 2 != 0)
                        return -EINVAL;
                samples1 = samples / 2;
@@ -405,9 +405,9 @@ ssize_t snd_pcm_format_set_silence(int format, void *data, size_t samples)
 
 static int linear_formats[4*2*2] = {
        SND_PCM_FORMAT_S8,
-       SND_PCM_FORMAT_U8,
        SND_PCM_FORMAT_S8,
        SND_PCM_FORMAT_U8,
+       SND_PCM_FORMAT_U8,
        SND_PCM_FORMAT_S16_LE,
        SND_PCM_FORMAT_S16_BE,
        SND_PCM_FORMAT_U16_LE,
index 0ade84abcea5cee2d9867c0896a92b49fe2ceb22..d362aae6b54a9f60fe48a686718cd9afa6822fdb 100644 (file)
@@ -52,10 +52,10 @@ const snd_pcm_channel_area_t *snd_pcm_mmap_areas(snd_pcm_t *pcm)
        return pcm->running_areas;
 }
 
-size_t snd_pcm_mmap_playback_xfer(snd_pcm_t *pcm, size_t frames)
+snd_pcm_uframes_t snd_pcm_mmap_playback_xfer(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
 {
-       size_t cont;
-       size_t avail = snd_pcm_mmap_playback_avail(pcm);
+       snd_pcm_uframes_t cont;
+       snd_pcm_uframes_t avail = snd_pcm_mmap_playback_avail(pcm);
        if (avail < frames)
                frames = avail;
        cont = pcm->buffer_size - *pcm->appl_ptr % pcm->buffer_size;
@@ -64,10 +64,10 @@ size_t snd_pcm_mmap_playback_xfer(snd_pcm_t *pcm, size_t frames)
        return frames;
 }
 
-size_t snd_pcm_mmap_capture_xfer(snd_pcm_t *pcm, size_t frames)
+snd_pcm_uframes_t snd_pcm_mmap_capture_xfer(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
 {
-       size_t cont;
-       size_t avail = snd_pcm_mmap_capture_avail(pcm);
+       snd_pcm_uframes_t cont;
+       snd_pcm_uframes_t avail = snd_pcm_mmap_capture_avail(pcm);
        if (avail < frames)
                frames = avail;
        cont = pcm->buffer_size - *pcm->appl_ptr % pcm->buffer_size;
@@ -76,7 +76,7 @@ size_t snd_pcm_mmap_capture_xfer(snd_pcm_t *pcm, size_t frames)
        return frames;
 }
 
-size_t snd_pcm_mmap_xfer(snd_pcm_t *pcm, size_t frames)
+snd_pcm_uframes_t snd_pcm_mmap_xfer(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
 {
         assert(pcm);
        if (pcm->stream == SND_PCM_STREAM_PLAYBACK)
@@ -85,73 +85,73 @@ size_t snd_pcm_mmap_xfer(snd_pcm_t *pcm, size_t frames)
                return snd_pcm_mmap_capture_xfer(pcm, frames);
 }
 
-size_t snd_pcm_mmap_offset(snd_pcm_t *pcm)
+snd_pcm_uframes_t snd_pcm_mmap_offset(snd_pcm_t *pcm)
 {
         assert(pcm);
        return *pcm->appl_ptr % pcm->buffer_size;
 }
 
-size_t snd_pcm_mmap_hw_offset(snd_pcm_t *pcm)
+snd_pcm_uframes_t snd_pcm_mmap_hw_offset(snd_pcm_t *pcm)
 {
         assert(pcm);
        return *pcm->hw_ptr % pcm->buffer_size;
 }
 
-void snd_pcm_mmap_appl_backward(snd_pcm_t *pcm, size_t frames)
+void snd_pcm_mmap_appl_backward(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
 {
-       ssize_t appl_ptr = *pcm->appl_ptr;
+       snd_pcm_sframes_t appl_ptr = *pcm->appl_ptr;
        appl_ptr -= frames;
        if (appl_ptr < 0)
                appl_ptr += pcm->boundary;
        *pcm->appl_ptr = appl_ptr;
 }
 
-void snd_pcm_mmap_appl_forward(snd_pcm_t *pcm, size_t frames)
+void snd_pcm_mmap_appl_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
 {
-       size_t appl_ptr = *pcm->appl_ptr;
+       snd_pcm_uframes_t appl_ptr = *pcm->appl_ptr;
        appl_ptr += frames;
        if (appl_ptr >= pcm->boundary)
                appl_ptr -= pcm->boundary;
        *pcm->appl_ptr = appl_ptr;
 }
 
-void snd_pcm_mmap_hw_backward(snd_pcm_t *pcm, size_t frames)
+void snd_pcm_mmap_hw_backward(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
 {
-       ssize_t hw_ptr = *pcm->hw_ptr;
+       snd_pcm_sframes_t hw_ptr = *pcm->hw_ptr;
        hw_ptr -= frames;
        if (hw_ptr < 0)
                hw_ptr += pcm->boundary;
        *pcm->hw_ptr = hw_ptr;
 }
 
-void snd_pcm_mmap_hw_forward(snd_pcm_t *pcm, size_t frames)
+void snd_pcm_mmap_hw_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
 {
-       size_t hw_ptr = *pcm->hw_ptr;
+       snd_pcm_uframes_t hw_ptr = *pcm->hw_ptr;
        hw_ptr += frames;
        if (hw_ptr >= pcm->boundary)
                hw_ptr -= pcm->boundary;
        *pcm->hw_ptr = hw_ptr;
 }
 
-ssize_t snd_pcm_mmap_write_areas(snd_pcm_t *pcm,
+snd_pcm_sframes_t snd_pcm_mmap_write_areas(snd_pcm_t *pcm,
                                 const snd_pcm_channel_area_t *areas,
-                                size_t offset,
-                                size_t size,
-                                size_t *slave_sizep)
+                                snd_pcm_uframes_t offset,
+                                snd_pcm_uframes_t size,
+                                snd_pcm_uframes_t *slave_sizep)
 {
-       size_t xfer;
+       snd_pcm_uframes_t xfer;
        if (slave_sizep && *slave_sizep < size)
                size = *slave_sizep;
        xfer = 0;
        while (xfer < size) {
-               size_t frames = snd_pcm_mmap_playback_xfer(pcm, size - xfer);
-               ssize_t err;
+               snd_pcm_uframes_t frames = snd_pcm_mmap_playback_xfer(pcm, size - xfer);
+               snd_pcm_sframes_t err;
                snd_pcm_areas_copy(areas, offset, 
                                   snd_pcm_mmap_areas(pcm), snd_pcm_mmap_offset(pcm),
                                   pcm->channels, 
                                   frames, pcm->format);
                err = snd_pcm_mmap_forward(pcm, frames);
-               assert(err == (ssize_t)frames);
+               assert(err == (snd_pcm_sframes_t)frames);
                offset += frames;
                xfer += frames;
        }
@@ -160,25 +160,25 @@ ssize_t snd_pcm_mmap_write_areas(snd_pcm_t *pcm,
        return xfer;
 }
 
-ssize_t snd_pcm_mmap_read_areas(snd_pcm_t *pcm,
+snd_pcm_sframes_t snd_pcm_mmap_read_areas(snd_pcm_t *pcm,
                                const snd_pcm_channel_area_t *areas,
-                               size_t offset,
-                               size_t size,
-                               size_t *slave_sizep)
+                               snd_pcm_uframes_t offset,
+                               snd_pcm_uframes_t size,
+                               snd_pcm_uframes_t *slave_sizep)
 {
-       size_t xfer;
+       snd_pcm_uframes_t xfer;
        if (slave_sizep && *slave_sizep < size)
                size = *slave_sizep;
        xfer = 0;
        while (xfer < size) {
-               size_t frames = snd_pcm_mmap_capture_xfer(pcm, size - xfer);
-               ssize_t err;
+               snd_pcm_uframes_t frames = snd_pcm_mmap_capture_xfer(pcm, size - xfer);
+               snd_pcm_sframes_t err;
                snd_pcm_areas_copy(snd_pcm_mmap_areas(pcm), snd_pcm_mmap_offset(pcm),
                                   areas, offset, 
                                   pcm->channels, 
                                   frames, pcm->format);
                err = snd_pcm_mmap_forward(pcm, frames);
-               assert(err == (ssize_t)frames);
+               assert(err == (snd_pcm_sframes_t)frames);
                offset += frames;
                xfer += frames;
        }
@@ -187,7 +187,7 @@ ssize_t snd_pcm_mmap_read_areas(snd_pcm_t *pcm,
        return xfer;
 }
 
-ssize_t snd_pcm_mmap_writei(snd_pcm_t *pcm, const void *buffer, size_t size)
+snd_pcm_sframes_t snd_pcm_mmap_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size)
 {
        snd_pcm_channel_area_t areas[pcm->channels];
        snd_pcm_areas_from_buf(pcm, areas, (void*)buffer);
@@ -195,7 +195,7 @@ ssize_t snd_pcm_mmap_writei(snd_pcm_t *pcm, const void *buffer, size_t size)
                                   snd_pcm_mmap_write_areas);
 }
 
-ssize_t snd_pcm_mmap_writen(snd_pcm_t *pcm, void **bufs, size_t size)
+snd_pcm_sframes_t snd_pcm_mmap_writen(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size)
 {
        snd_pcm_channel_area_t areas[pcm->channels];
        snd_pcm_areas_from_bufs(pcm, areas, bufs);
@@ -203,7 +203,7 @@ ssize_t snd_pcm_mmap_writen(snd_pcm_t *pcm, void **bufs, size_t size)
                                   snd_pcm_mmap_write_areas);
 }
 
-ssize_t snd_pcm_mmap_readi(snd_pcm_t *pcm, void *buffer, size_t size)
+snd_pcm_sframes_t snd_pcm_mmap_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size)
 {
        snd_pcm_channel_area_t areas[pcm->channels];
        snd_pcm_areas_from_buf(pcm, areas, buffer);
@@ -211,7 +211,7 @@ ssize_t snd_pcm_mmap_readi(snd_pcm_t *pcm, void *buffer, size_t size)
                                  snd_pcm_mmap_read_areas);
 }
 
-ssize_t snd_pcm_mmap_readn(snd_pcm_t *pcm, void **bufs, size_t size)
+snd_pcm_sframes_t snd_pcm_mmap_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size)
 {
        snd_pcm_channel_area_t areas[pcm->channels];
        snd_pcm_areas_from_bufs(pcm, areas, bufs);
@@ -421,15 +421,15 @@ int snd_pcm_munmap(snd_pcm_t *pcm)
        return 0;
 }
 
-ssize_t snd_pcm_write_mmap(snd_pcm_t *pcm, size_t size)
+snd_pcm_sframes_t snd_pcm_write_mmap(snd_pcm_t *pcm, snd_pcm_uframes_t size)
 {
-       size_t xfer = 0;
-       ssize_t err = 0;
+       snd_pcm_uframes_t xfer = 0;
+       snd_pcm_sframes_t err = 0;
        assert(size > 0);
        while (xfer < size) {
-               size_t frames = size - xfer;
-               size_t offset = snd_pcm_mmap_hw_offset(pcm);
-               size_t cont = pcm->buffer_size - offset;
+               snd_pcm_uframes_t frames = size - xfer;
+               snd_pcm_uframes_t offset = snd_pcm_mmap_hw_offset(pcm);
+               snd_pcm_uframes_t cont = pcm->buffer_size - offset;
                if (cont < frames)
                        frames = cont;
                switch (pcm->access) {
@@ -442,7 +442,7 @@ ssize_t snd_pcm_write_mmap(snd_pcm_t *pcm, size_t size)
                }
                case SND_PCM_ACCESS_MMAP_NONINTERLEAVED:
                {
-                       size_t channels = pcm->channels;
+                       unsigned int channels = pcm->channels;
                        unsigned int c;
                        void *bufs[channels];
                        const snd_pcm_channel_area_t *areas = snd_pcm_mmap_areas(pcm);
@@ -467,15 +467,15 @@ ssize_t snd_pcm_write_mmap(snd_pcm_t *pcm, size_t size)
        return err;
 }
 
-ssize_t snd_pcm_read_mmap(snd_pcm_t *pcm, size_t size)
+snd_pcm_sframes_t snd_pcm_read_mmap(snd_pcm_t *pcm, snd_pcm_uframes_t size)
 {
-       size_t xfer = 0;
-       ssize_t err = 0;
+       snd_pcm_uframes_t xfer = 0;
+       snd_pcm_sframes_t err = 0;
        assert(size > 0);
        while (xfer < size) {
-               size_t frames = size - xfer;
-               size_t offset = snd_pcm_mmap_hw_offset(pcm);
-               size_t cont = pcm->buffer_size - offset;
+               snd_pcm_uframes_t frames = size - xfer;
+               snd_pcm_uframes_t offset = snd_pcm_mmap_hw_offset(pcm);
+               snd_pcm_uframes_t cont = pcm->buffer_size - offset;
                if (cont < frames)
                        frames = cont;
                switch (pcm->access) {
@@ -488,7 +488,7 @@ ssize_t snd_pcm_read_mmap(snd_pcm_t *pcm, size_t size)
                }
                case SND_PCM_ACCESS_MMAP_NONINTERLEAVED:
                {
-                       size_t channels = pcm->channels;
+                       snd_pcm_uframes_t channels = pcm->channels;
                        unsigned int c;
                        void *bufs[channels];
                        const snd_pcm_channel_area_t *areas = snd_pcm_mmap_areas(pcm);
index 5f66346482c49b66e272f1b996d134d3b72c3702..ff67c6d37386bffe064ab5490114b5f52c2b4e04 100644 (file)
 #include "pcm_plugin.h"
 
 typedef void (*mulaw_f)(const snd_pcm_channel_area_t *src_areas,
-                       size_t src_offset,
+                       snd_pcm_uframes_t src_offset,
                        const snd_pcm_channel_area_t *dst_areas,
-                       size_t dst_offset,
-                       size_t channels, size_t frames, int getputidx);
+                       snd_pcm_uframes_t dst_offset,
+                       unsigned int channels, snd_pcm_uframes_t frames, int getputidx);
 
 typedef struct {
        /* This field need to be the first */
@@ -138,21 +138,21 @@ static int ulaw_to_s16(unsigned char u_val)
 }
 
 static void mulaw_decode(const snd_pcm_channel_area_t *src_areas,
-                        size_t src_offset,
+                        snd_pcm_uframes_t src_offset,
                         const snd_pcm_channel_area_t *dst_areas,
-                        size_t dst_offset,
-                        size_t channels, size_t frames, int putidx)
+                        snd_pcm_uframes_t dst_offset,
+                        unsigned int channels, snd_pcm_uframes_t frames, int putidx)
 {
 #define PUT16_LABELS
 #include "plugin_ops.h"
 #undef PUT16_LABELS
        void *put = put16_labels[putidx];
-       size_t channel;
+       unsigned int channel;
        for (channel = 0; channel < channels; ++channel) {
                char *src;
                char *dst;
                int src_step, dst_step;
-               size_t frames1;
+               snd_pcm_uframes_t frames1;
                const snd_pcm_channel_area_t *src_area = &src_areas[channel];
                const snd_pcm_channel_area_t *dst_area = &dst_areas[channel];
 #if 0
@@ -183,22 +183,22 @@ static void mulaw_decode(const snd_pcm_channel_area_t *src_areas,
 }
 
 static void mulaw_encode(const snd_pcm_channel_area_t *src_areas,
-                        size_t src_offset,
+                        snd_pcm_uframes_t src_offset,
                         const snd_pcm_channel_area_t *dst_areas,
-                        size_t dst_offset,
-                        size_t channels, size_t frames, int getidx)
+                        snd_pcm_uframes_t dst_offset,
+                        unsigned int channels, snd_pcm_uframes_t frames, int getidx)
 {
 #define GET16_LABELS
 #include "plugin_ops.h"
 #undef GET16_LABELS
        void *get = get16_labels[getidx];
-       size_t channel;
+       unsigned int channel;
        int16_t sample = 0;
        for (channel = 0; channel < channels; ++channel) {
                char *src;
                char *dst;
                int src_step, dst_step;
-               size_t frames1;
+               snd_pcm_uframes_t frames1;
                const snd_pcm_channel_area_t *src_area = &src_areas[channel];
                const snd_pcm_channel_area_t *dst_area = &dst_areas[channel];
 #if 0
@@ -233,51 +233,58 @@ static int snd_pcm_mulaw_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
        snd_pcm_mulaw_t *mulaw = pcm->private;
        snd_pcm_t *slave = mulaw->plug.slave;
        int err;
+       unsigned int cmask, lcmask;
        snd_pcm_hw_params_t sparams;
        mask_t *access_mask = alloca(mask_sizeof());
        mask_t *saccess_mask = alloca(mask_sizeof());
        mask_load(access_mask, SND_PCM_ACCBIT_PLUGIN);
        mask_load(saccess_mask, SND_PCM_ACCBIT_MMAP);
-       err = _snd_pcm_hw_param_mask(params, 1, SND_PCM_HW_PARAM_ACCESS,
+       cmask = params->cmask;
+       params->cmask = 0;
+       err = _snd_pcm_hw_param_mask(params, SND_PCM_HW_PARAM_ACCESS,
                                     access_mask);
        if (err < 0)
                return err;
        if (mulaw->sformat == SND_PCM_FORMAT_MU_LAW) {
                mask_t *format_mask = alloca(mask_sizeof());
                mask_load(format_mask, SND_PCM_FMTBIT_LINEAR);
-               err = _snd_pcm_hw_param_mask(params, 1, 
+               err = _snd_pcm_hw_param_mask(params,
                                             SND_PCM_HW_PARAM_FORMAT,
                                             format_mask);
                if (err < 0)
                        return err;
        } else {
-               err = _snd_pcm_hw_param_set(params, 1,
+               err = _snd_pcm_hw_param_set(params,
                                            SND_PCM_HW_PARAM_FORMAT,
-                                           SND_PCM_FORMAT_MU_LAW);
+                                           SND_PCM_FORMAT_MU_LAW, 0);
                if (err < 0)
                        return err;
        }
-       err = _snd_pcm_hw_param_set(params, 1, SND_PCM_HW_PARAM_SUBFORMAT,
-                                   SND_PCM_SUBFORMAT_STD);
+       err = _snd_pcm_hw_param_set(params, SND_PCM_HW_PARAM_SUBFORMAT,
+                                   SND_PCM_SUBFORMAT_STD, 0);
        if (err < 0)
                return err;
+       lcmask = params->cmask;
+       params->cmask |= cmask;
 
        _snd_pcm_hw_params_any(&sparams);
-       _snd_pcm_hw_param_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
+       _snd_pcm_hw_param_mask(&sparams, SND_PCM_HW_PARAM_ACCESS,
                               saccess_mask);
-       _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_FORMAT,
-                             mulaw->sformat);
-       _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_SUBFORMAT,
-                             SND_PCM_SUBFORMAT_STD);
+       _snd_pcm_hw_param_set(&sparams, SND_PCM_HW_PARAM_FORMAT,
+                             mulaw->sformat, 0);
+       _snd_pcm_hw_param_set(&sparams, SND_PCM_HW_PARAM_SUBFORMAT,
+                             SND_PCM_SUBFORMAT_STD, 0);
        err = snd_pcm_hw_refine2(params, &sparams,
-                                snd_pcm_hw_refine, slave,
+                                snd_pcm_generic_hw_link, slave,
                                 SND_PCM_HW_PARBIT_CHANNELS |
                                 SND_PCM_HW_PARBIT_RATE |
-                                SND_PCM_HW_PARBIT_FRAGMENT_SIZE |
+                                SND_PCM_HW_PARBIT_PERIOD_SIZE |
                                 SND_PCM_HW_PARBIT_BUFFER_SIZE |
-                                SND_PCM_HW_PARBIT_FRAGMENTS |
-                                SND_PCM_HW_PARBIT_FRAGMENT_LENGTH |
-                                SND_PCM_HW_PARBIT_BUFFER_LENGTH);
+                                SND_PCM_HW_PARBIT_PERIODS |
+                                SND_PCM_HW_PARBIT_PERIOD_TIME |
+                                SND_PCM_HW_PARBIT_BUFFER_TIME |
+                                SND_PCM_HW_PARBIT_TICK_TIME);
+       params->cmask |= lcmask;
        if (err < 0)
                return err;
        params->info &= ~(SND_PCM_INFO_MMAP | SND_PCM_INFO_MMAP_VALID);
@@ -289,32 +296,40 @@ static int snd_pcm_mulaw_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
        snd_pcm_mulaw_t *mulaw = pcm->private;
        snd_pcm_t *slave = mulaw->plug.slave;
        int err;
+       unsigned int links;
        snd_pcm_hw_params_t sparams;
        mask_t *saccess_mask = alloca(mask_sizeof());
        mask_load(saccess_mask, SND_PCM_ACCBIT_MMAP);
 
        _snd_pcm_hw_params_any(&sparams);
-       _snd_pcm_hw_param_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
+       _snd_pcm_hw_param_mask(&sparams, SND_PCM_HW_PARAM_ACCESS,
                               saccess_mask);
-       _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_FORMAT,
-                             mulaw->sformat);
-       _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_SUBFORMAT,
-                             SND_PCM_SUBFORMAT_STD);
-       err = snd_pcm_hw_params2(params, &sparams,
-                                snd_pcm_hw_params, slave,
-                                SND_PCM_HW_PARBIT_CHANNELS |
-                                SND_PCM_HW_PARBIT_RATE |
-                                SND_PCM_HW_PARBIT_FRAGMENT_SIZE |
-                                SND_PCM_HW_PARBIT_BUFFER_SIZE |
-                                SND_PCM_HW_PARBIT_FRAGMENTS |
-                                SND_PCM_HW_PARBIT_FRAGMENT_LENGTH |
-                                SND_PCM_HW_PARBIT_BUFFER_LENGTH);
+       _snd_pcm_hw_param_set(&sparams, SND_PCM_HW_PARAM_FORMAT,
+                             mulaw->sformat, 0);
+       _snd_pcm_hw_param_set(&sparams, SND_PCM_HW_PARAM_SUBFORMAT,
+                             SND_PCM_SUBFORMAT_STD, 0);
+       links = SND_PCM_HW_PARBIT_CHANNELS |
+               SND_PCM_HW_PARBIT_RATE |
+               SND_PCM_HW_PARBIT_PERIOD_SIZE |
+               SND_PCM_HW_PARBIT_BUFFER_SIZE |
+               SND_PCM_HW_PARBIT_PERIODS |
+               SND_PCM_HW_PARBIT_PERIOD_TIME |
+               SND_PCM_HW_PARBIT_BUFFER_TIME |
+               SND_PCM_HW_PARBIT_TICK_TIME;
+       err = snd_pcm_hw_params_refine(&sparams, links, params);
+       assert(err >= 0);
+       err = _snd_pcm_hw_refine(&sparams);
+       assert(err >= 0);
+       err = snd_pcm_hw_params(slave, &sparams);
+       params->cmask = 0;
+       sparams.cmask = ~0U;
+       snd_pcm_hw_params_refine(params, links, &sparams);
        if (err < 0)
                return err;
        params->info &= ~(SND_PCM_INFO_MMAP | SND_PCM_INFO_MMAP_VALID);
        if (pcm->stream == SND_PCM_STREAM_PLAYBACK) {
                if (mulaw->sformat == SND_PCM_FORMAT_MU_LAW) {
-                       mulaw->getput_idx = get_index(snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FORMAT), SND_PCM_FORMAT_S16);
+                       mulaw->getput_idx = get_index(snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FORMAT, 0), SND_PCM_FORMAT_S16);
                        mulaw->func = mulaw_encode;
                } else {
                        mulaw->getput_idx = put_index(SND_PCM_FORMAT_S16, mulaw->sformat);
@@ -322,7 +337,7 @@ static int snd_pcm_mulaw_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
                }
        } else {
                if (mulaw->sformat == SND_PCM_FORMAT_MU_LAW) {
-                       mulaw->getput_idx = put_index(SND_PCM_FORMAT_S16, snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FORMAT));
+                       mulaw->getput_idx = put_index(SND_PCM_FORMAT_S16, snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FORMAT, 0));
                        mulaw->func = mulaw_decode;
                } else {
                        mulaw->getput_idx = get_index(mulaw->sformat, SND_PCM_FORMAT_S16);
@@ -332,21 +347,21 @@ static int snd_pcm_mulaw_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
        return 0;
 }
 
-static ssize_t snd_pcm_mulaw_write_areas(snd_pcm_t *pcm,
+static snd_pcm_sframes_t snd_pcm_mulaw_write_areas(snd_pcm_t *pcm,
                                         const snd_pcm_channel_area_t *areas,
-                                        size_t offset,
-                                        size_t size,
-                                        size_t *slave_sizep)
+                                        snd_pcm_uframes_t offset,
+                                        snd_pcm_uframes_t size,
+                                        snd_pcm_uframes_t *slave_sizep)
 {
        snd_pcm_mulaw_t *mulaw = pcm->private;
        snd_pcm_t *slave = mulaw->plug.slave;
-       size_t xfer = 0;
-       ssize_t err = 0;
+       snd_pcm_uframes_t xfer = 0;
+       snd_pcm_sframes_t err = 0;
        if (slave_sizep && *slave_sizep < size)
                size = *slave_sizep;
        assert(size > 0);
        while (xfer < size) {
-               size_t frames = snd_pcm_mmap_playback_xfer(slave, size - xfer);
+               snd_pcm_uframes_t frames = snd_pcm_mmap_playback_xfer(slave, size - xfer);
                mulaw->func(areas, offset, 
                            snd_pcm_mmap_areas(slave), snd_pcm_mmap_offset(slave),
                            pcm->channels, frames,
@@ -354,7 +369,7 @@ static ssize_t snd_pcm_mulaw_write_areas(snd_pcm_t *pcm,
                err = snd_pcm_mmap_forward(slave, frames);
                if (err < 0)
                        break;
-               assert((size_t)err == frames);
+               assert((snd_pcm_uframes_t)err == frames);
                offset += err;
                xfer += err;
                snd_pcm_mmap_hw_forward(pcm, err);
@@ -367,21 +382,21 @@ static ssize_t snd_pcm_mulaw_write_areas(snd_pcm_t *pcm,
        return err;
 }
 
-static ssize_t snd_pcm_mulaw_read_areas(snd_pcm_t *pcm,
+static snd_pcm_sframes_t snd_pcm_mulaw_read_areas(snd_pcm_t *pcm,
                                        const snd_pcm_channel_area_t *areas,
-                                       size_t offset,
-                                       size_t size,
-                                       size_t *slave_sizep)
+                                       snd_pcm_uframes_t offset,
+                                       snd_pcm_uframes_t size,
+                                       snd_pcm_uframes_t *slave_sizep)
 {
        snd_pcm_mulaw_t *mulaw = pcm->private;
        snd_pcm_t *slave = mulaw->plug.slave;
-       size_t xfer = 0;
-       ssize_t err = 0;
+       snd_pcm_uframes_t xfer = 0;
+       snd_pcm_sframes_t err = 0;
        if (slave_sizep && *slave_sizep < size)
                size = *slave_sizep;
        assert(size > 0);
        while (xfer < size) {
-               size_t frames = snd_pcm_mmap_capture_xfer(slave, size - xfer);
+               snd_pcm_uframes_t frames = snd_pcm_mmap_capture_xfer(slave, size - xfer);
                mulaw->func(snd_pcm_mmap_areas(slave), snd_pcm_mmap_offset(slave),
                            areas, offset, 
                            pcm->channels, frames,
@@ -389,7 +404,7 @@ static ssize_t snd_pcm_mulaw_read_areas(snd_pcm_t *pcm,
                err = snd_pcm_mmap_forward(slave, frames);
                if (err < 0)
                        break;
-               assert((size_t)err == frames);
+               assert((snd_pcm_uframes_t)err == frames);
                offset += err;
                xfer += err;
                snd_pcm_mmap_hw_forward(pcm, err);
index 4cb55f8d1c847547121d18e8af10562b6e7f25a7..28719ae8925c9ef38d04d014dfadc7b9833b7534 100644 (file)
@@ -40,16 +40,16 @@ typedef struct {
 } snd_pcm_multi_channel_t;
 
 typedef struct {
-       size_t slaves_count;
+       unsigned int slaves_count;
        snd_pcm_multi_slave_t *slaves;
-       size_t channels_count;
+       unsigned int channels_count;
        snd_pcm_multi_channel_t *channels;
 } snd_pcm_multi_t;
 
 static int snd_pcm_multi_close(snd_pcm_t *pcm)
 {
        snd_pcm_multi_t *multi = pcm->private;
-       size_t i;
+       unsigned int i;
        int ret = 0;
        for (i = 0; i < multi->slaves_count; ++i) {
                int err;
@@ -102,7 +102,8 @@ static int snd_pcm_multi_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
        unsigned int k;
        snd_pcm_hw_params_t sparams;
        int changed = 0;
-       int err;
+       int err = 0;
+       unsigned int cmask, lcmask;
        const mask_t *access_mask = snd_pcm_hw_param_value_mask(params, SND_PCM_HW_PARAM_ACCESS);
        mask_t *saccess_mask = alloca(mask_sizeof());
        if (mask_test(access_mask, SND_PCM_ACCESS_RW_INTERLEAVED) ||
@@ -122,38 +123,50 @@ static int snd_pcm_multi_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
                }
        }
                
-       err = _snd_pcm_hw_param_set(params, 1, SND_PCM_HW_PARAM_CHANNELS,
-                                    multi->channels_count);
+       cmask = params->cmask;
+       params->cmask = 0;
+       err = _snd_pcm_hw_param_set(params, SND_PCM_HW_PARAM_CHANNELS,
+                                   multi->channels_count, 0);
        if (err < 0)
                return err;
+       lcmask = params->cmask;
+       cmask |= params->cmask;
+       
        changed = 0;
        do {
                for (k = 0; k < multi->slaves_count; ++k) {
                        snd_pcm_t *slave = multi->slaves[k].pcm;
+                       params->cmask = cmask;
                        _snd_pcm_hw_params_any(&sparams);
-                       _snd_pcm_hw_param_mask(&sparams, 0,
-                                               SND_PCM_HW_PARAM_ACCESS,
-                                               saccess_mask);
-                       _snd_pcm_hw_param_set(&sparams, 0,
-                                              SND_PCM_HW_PARAM_CHANNELS,
-                                              multi->slaves[k].channels_count);
+                       _snd_pcm_hw_param_mask(&sparams,
+                                              SND_PCM_HW_PARAM_ACCESS,
+                                              saccess_mask);
+                       _snd_pcm_hw_param_set(&sparams,
+                                             SND_PCM_HW_PARAM_CHANNELS,
+                                             multi->slaves[k].channels_count, 0);
                        err = snd_pcm_hw_refine2(params, &sparams,
-                                                snd_pcm_hw_refine, slave,
+                                                snd_pcm_generic_hw_link, slave,
                                                 SND_PCM_HW_PARBIT_FORMAT |
                                                 SND_PCM_HW_PARBIT_SUBFORMAT |
                                                 SND_PCM_HW_PARBIT_RATE |
-                                                SND_PCM_HW_PARBIT_FRAGMENT_SIZE |
-                                                SND_PCM_HW_PARBIT_FRAGMENT_LENGTH |
+                                                SND_PCM_HW_PARBIT_PERIOD_SIZE |
+                                                SND_PCM_HW_PARBIT_PERIOD_TIME |
                                                 SND_PCM_HW_PARBIT_BUFFER_SIZE |
-                                                SND_PCM_HW_PARBIT_BUFFER_LENGTH |
-                                                SND_PCM_HW_PARBIT_FRAGMENTS);
-                       if (err < 0)
-                               return err;
-                       if (params->hw_cmask)
+                                                SND_PCM_HW_PARBIT_BUFFER_TIME |
+                                                SND_PCM_HW_PARBIT_PERIODS |
+                                                SND_PCM_HW_PARBIT_TICK_TIME);
+                       if (params->cmask) {
                                changed++;
+                               lcmask |= params->cmask;
+                               cmask |= params->cmask;
+                       }
+                       if (err < 0)
+                               goto _end;
                }
        } while (changed && multi->slaves_count > 1);
-       return 0;
+ _end:
+       params->cmask = lcmask;
+       return err;
 }
 
 static int snd_pcm_multi_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
@@ -163,6 +176,16 @@ static int snd_pcm_multi_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
        int err;
        const mask_t *access_mask = snd_pcm_hw_param_value_mask(params, SND_PCM_HW_PARAM_ACCESS);
        mask_t *saccess_mask = alloca(mask_sizeof());
+       unsigned int links;
+       links = SND_PCM_HW_PARBIT_FORMAT |
+               SND_PCM_HW_PARBIT_SUBFORMAT |
+               SND_PCM_HW_PARBIT_RATE |
+               SND_PCM_HW_PARBIT_PERIOD_SIZE |
+               SND_PCM_HW_PARBIT_PERIOD_TIME |
+               SND_PCM_HW_PARBIT_BUFFER_SIZE |
+               SND_PCM_HW_PARBIT_BUFFER_TIME |
+               SND_PCM_HW_PARBIT_PERIODS |
+               SND_PCM_HW_PARBIT_TICK_TIME;
        if (mask_test(access_mask, SND_PCM_ACCESS_RW_INTERLEAVED) ||
            mask_test(access_mask, SND_PCM_ACCESS_RW_NONINTERLEAVED))
                mask_load(saccess_mask, SND_PCM_ACCBIT_MMAP);
@@ -183,20 +206,18 @@ static int snd_pcm_multi_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
                snd_pcm_t *slave = multi->slaves[k].pcm;
                snd_pcm_hw_params_t sparams;
                _snd_pcm_hw_params_any(&sparams);
-               _snd_pcm_hw_param_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
+               _snd_pcm_hw_param_mask(&sparams, SND_PCM_HW_PARAM_ACCESS,
                                        saccess_mask);
-               _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_CHANNELS,
-                                      multi->slaves[k].channels_count);
-               err = snd_pcm_hw_params2(params, &sparams,
-                                        snd_pcm_hw_params, slave,
-                                        SND_PCM_HW_PARBIT_FORMAT |
-                                        SND_PCM_HW_PARBIT_SUBFORMAT |
-                                        SND_PCM_HW_PARBIT_RATE |
-                                        SND_PCM_HW_PARBIT_FRAGMENT_SIZE |
-                                        SND_PCM_HW_PARBIT_FRAGMENT_LENGTH |
-                                        SND_PCM_HW_PARBIT_BUFFER_SIZE |
-                                        SND_PCM_HW_PARBIT_BUFFER_LENGTH |
-                                        SND_PCM_HW_PARBIT_FRAGMENTS);
+               _snd_pcm_hw_param_set(&sparams, SND_PCM_HW_PARAM_CHANNELS,
+                                      multi->slaves[k].channels_count, 0);
+               err = snd_pcm_hw_params_refine(&sparams, links, params);
+               assert(err >= 0);
+               err = _snd_pcm_hw_refine(&sparams);
+               assert(err >= 0);
+               err = snd_pcm_hw_params(slave, &sparams);
+               params->cmask = 0;
+               sparams.cmask = ~0U;
+               snd_pcm_hw_params_refine(params, links, &sparams);
                if (err < 0)
                        return err;
                err = snd_pcm_areas_silence(slave->running_areas, 0, slave->channels, slave->buffer_size, slave->format);
@@ -239,14 +260,14 @@ static int snd_pcm_multi_state(snd_pcm_t *pcm)
        return snd_pcm_state(slave);
 }
 
-static int snd_pcm_multi_delay(snd_pcm_t *pcm, ssize_t *delayp)
+static int snd_pcm_multi_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp)
 {
        snd_pcm_multi_t *multi = pcm->private;
        snd_pcm_t *slave = multi->slaves[0].pcm;
        return snd_pcm_delay(slave, delayp);
 }
 
-static ssize_t snd_pcm_multi_avail_update(snd_pcm_t *pcm)
+static snd_pcm_sframes_t snd_pcm_multi_avail_update(snd_pcm_t *pcm)
 {
        snd_pcm_multi_t *multi = pcm->private;
        snd_pcm_t *slave = multi->slaves[0].pcm;
@@ -303,15 +324,15 @@ static int snd_pcm_multi_channel_info(snd_pcm_t *pcm, snd_pcm_channel_info_t *in
        return err;
 }
 
-static ssize_t snd_pcm_multi_rewind(snd_pcm_t *pcm, size_t frames)
+static snd_pcm_sframes_t snd_pcm_multi_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
 {
        snd_pcm_multi_t *multi = pcm->private;
        unsigned int i;
-       size_t pos[multi->slaves_count];
+       snd_pcm_uframes_t pos[multi->slaves_count];
        memset(pos, 0, sizeof(pos));
        for (i = 0; i < multi->slaves_count; ++i) {
                snd_pcm_t *slave_i = multi->slaves[i].pcm;
-               ssize_t f = snd_pcm_rewind(slave_i, frames);
+               snd_pcm_sframes_t f = snd_pcm_rewind(slave_i, frames);
                if (f < 0)
                        return f;
                pos[i] = f;
@@ -320,28 +341,28 @@ static ssize_t snd_pcm_multi_rewind(snd_pcm_t *pcm, size_t frames)
        /* Realign the pointers */
        for (i = 0; i < multi->slaves_count; ++i) {
                snd_pcm_t *slave_i = multi->slaves[i].pcm;
-               size_t f = pos[i] - frames;
+               snd_pcm_uframes_t f = pos[i] - frames;
                if (f > 0)
                        snd_pcm_mmap_appl_forward(slave_i, f);
        }
        return frames;
 }
 
-static ssize_t snd_pcm_multi_mmap_forward(snd_pcm_t *pcm, size_t size)
+static snd_pcm_sframes_t snd_pcm_multi_mmap_forward(snd_pcm_t *pcm, snd_pcm_uframes_t size)
 {
        snd_pcm_multi_t *multi = pcm->private;
        unsigned int i;
 
        for (i = 0; i < multi->slaves_count; ++i) {
                snd_pcm_t *slave = multi->slaves[i].pcm;
-               ssize_t frames = snd_pcm_mmap_forward(slave, size);
+               snd_pcm_sframes_t frames = snd_pcm_mmap_forward(slave, size);
                if (frames < 0)
                        return frames;
                if (i == 0) {
                        size = frames;
                        continue;
                }
-               if ((size_t) frames != size)
+               if ((snd_pcm_uframes_t) frames != size)
                        return -EBADFD;
        }
        return size;
@@ -422,9 +443,9 @@ snd_pcm_fast_ops_t snd_pcm_multi_fast_ops = {
 };
 
 int snd_pcm_multi_open(snd_pcm_t **pcmp, char *name,
-                      size_t slaves_count,
-                      snd_pcm_t **slaves_pcm, size_t *schannels_count,
-                      size_t channels_count,
+                      unsigned int slaves_count,
+                      snd_pcm_t **slaves_pcm, unsigned int *schannels_count,
+                      unsigned int channels_count,
                       int *sidxs, unsigned int *schannels,
                       int close_slaves)
 {
@@ -505,11 +526,11 @@ int _snd_pcm_multi_open(snd_pcm_t **pcmp, char *name, snd_config_t *conf,
        char **slaves_id = NULL;
        char **slaves_name = NULL;
        snd_pcm_t **slaves_pcm = NULL;
-       size_t *slaves_channels = NULL;
+       unsigned int *slaves_channels = NULL;
        unsigned int *channels_sidx = NULL;
        unsigned int *channels_schannel = NULL;
-       size_t slaves_count = 0;
-       size_t channels_count = 0;
+       unsigned int slaves_count = 0;
+       unsigned int channels_count = 0;
        snd_config_foreach(i, conf) {
                snd_config_t *n = snd_config_entry(i);
                if (strcmp(n->id, "comment") == 0)
@@ -667,7 +688,7 @@ int _snd_pcm_multi_open(snd_pcm_t **pcmp, char *name, snd_config_t *conf,
                        err = -EINVAL;
                        goto _free;
                }
-               if (slave < 0 || (size_t)slave >= slaves_count) {
+               if (slave < 0 || (unsigned int)slave >= slaves_count) {
                        ERR("Invalid or missing sidx");
                        err = -EINVAL;
                        goto _free;
index 3390e49c95258c17bbaccbf77ff1980c1b6fd435..f2e6e148ef9eb13ad956aa11254099ff7b37dc88 100644 (file)
@@ -29,8 +29,8 @@ typedef struct {
        snd_timestamp_t trigger_time;
        int state;
        int shmid;
-       size_t appl_ptr;
-       size_t hw_ptr;
+       snd_pcm_uframes_t appl_ptr;
+       snd_pcm_uframes_t hw_ptr;
        int poll_fd;
 } snd_pcm_null_t;
 
@@ -88,7 +88,7 @@ static int snd_pcm_null_state(snd_pcm_t *pcm)
        return null->state;
 }
 
-static int snd_pcm_null_delay(snd_pcm_t *pcm ATTRIBUTE_UNUSED, ssize_t *delayp)
+static int snd_pcm_null_delay(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_sframes_t *delayp)
 {
        *delayp = 0;
        return 0;
@@ -149,7 +149,7 @@ static int snd_pcm_null_pause(snd_pcm_t *pcm, int enable)
        return 0;
 }
 
-static ssize_t snd_pcm_null_rewind(snd_pcm_t *pcm, size_t frames)
+static snd_pcm_sframes_t snd_pcm_null_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
 {
        snd_pcm_null_t *null = pcm->private;
        switch (null->state) {
@@ -163,7 +163,7 @@ static ssize_t snd_pcm_null_rewind(snd_pcm_t *pcm, size_t frames)
        }
 }
 
-static ssize_t snd_pcm_null_fwd(snd_pcm_t *pcm, size_t size)
+static snd_pcm_sframes_t snd_pcm_null_fwd(snd_pcm_t *pcm, snd_pcm_uframes_t size)
 {
        snd_pcm_null_t *null = pcm->private;
        switch (null->state) {
@@ -177,7 +177,7 @@ static ssize_t snd_pcm_null_fwd(snd_pcm_t *pcm, size_t size)
        }
 }
 
-static ssize_t snd_pcm_null_writei(snd_pcm_t *pcm, const void *buffer ATTRIBUTE_UNUSED, size_t size)
+static snd_pcm_sframes_t snd_pcm_null_writei(snd_pcm_t *pcm, const void *buffer ATTRIBUTE_UNUSED, snd_pcm_uframes_t size)
 {
        snd_pcm_null_t *null = pcm->private;
        if (null->state == SND_PCM_STATE_PREPARED &&
@@ -187,7 +187,7 @@ static ssize_t snd_pcm_null_writei(snd_pcm_t *pcm, const void *buffer ATTRIBUTE_
        return snd_pcm_null_fwd(pcm, size);
 }
 
-static ssize_t snd_pcm_null_writen(snd_pcm_t *pcm, void **bufs ATTRIBUTE_UNUSED, size_t size)
+static snd_pcm_sframes_t snd_pcm_null_writen(snd_pcm_t *pcm, void **bufs ATTRIBUTE_UNUSED, snd_pcm_uframes_t size)
 {
        snd_pcm_null_t *null = pcm->private;
        if (null->state == SND_PCM_STATE_PREPARED &&
@@ -197,7 +197,7 @@ static ssize_t snd_pcm_null_writen(snd_pcm_t *pcm, void **bufs ATTRIBUTE_UNUSED,
        return snd_pcm_null_fwd(pcm, size);
 }
 
-static ssize_t snd_pcm_null_readi(snd_pcm_t *pcm, void *buffer ATTRIBUTE_UNUSED, size_t size)
+static snd_pcm_sframes_t snd_pcm_null_readi(snd_pcm_t *pcm, void *buffer ATTRIBUTE_UNUSED, snd_pcm_uframes_t size)
 {
        snd_pcm_null_t *null = pcm->private;
        if (null->state == SND_PCM_STATE_PREPARED &&
@@ -208,7 +208,7 @@ static ssize_t snd_pcm_null_readi(snd_pcm_t *pcm, void *buffer ATTRIBUTE_UNUSED,
        return snd_pcm_null_fwd(pcm, size);
 }
 
-static ssize_t snd_pcm_null_readn(snd_pcm_t *pcm, void **bufs ATTRIBUTE_UNUSED, size_t size)
+static snd_pcm_sframes_t snd_pcm_null_readn(snd_pcm_t *pcm, void **bufs ATTRIBUTE_UNUSED, snd_pcm_uframes_t size)
 {
        snd_pcm_null_t *null = pcm->private;
        if (null->state == SND_PCM_STATE_PREPARED &&
@@ -219,12 +219,12 @@ static ssize_t snd_pcm_null_readn(snd_pcm_t *pcm, void **bufs ATTRIBUTE_UNUSED,
        return snd_pcm_null_fwd(pcm, size);
 }
 
-static ssize_t snd_pcm_null_mmap_forward(snd_pcm_t *pcm, size_t size)
+static snd_pcm_sframes_t snd_pcm_null_mmap_forward(snd_pcm_t *pcm, snd_pcm_uframes_t size)
 {
        return snd_pcm_null_fwd(pcm, size);
 }
 
-static ssize_t snd_pcm_null_avail_update(snd_pcm_t *pcm)
+static snd_pcm_sframes_t snd_pcm_null_avail_update(snd_pcm_t *pcm)
 {
        return pcm->buffer_size;
 }
index 0d126f11502eb22b62757532b05c6f0f22bade91..154a53aa1071022b7434915acc8e677a11a0efb8 100644 (file)
 #include "interval.h"
 #include "mask.h"
 
-static inline unsigned int add(unsigned int a, unsigned int b)
-{
-       if (a >= UINT_MAX - b)
-               return UINT_MAX;
-       return a + b;
-}
-
-static inline unsigned int sub(unsigned int a, unsigned int b)
-{
-       if (a > b)
-               return a - b;
-       return 0;
+static void approx_sub(int a, int adir,
+                      int b, int bdir,
+                      int *c, int *cdir)
+{
+       adir = adir < 0 ? -1 : (adir > 0 ? 1 : 0);
+       bdir = bdir < 0 ? -1 : (bdir > 0 ? 1 : 0);
+       *c = a - b;
+       *cdir = adir - bdir;
+       if (*cdir == -2) {
+               assert(*c > INT_MIN);
+               (*c)--;
+       } else if (*cdir == 2) {
+               assert(*c < INT_MAX);
+               (*c)++;
+       }
+}
+
+static int approx_lt(unsigned int a, int adir,
+                    unsigned int b, int bdir)
+{
+       assert(a > 0 || adir >= 0);
+       assert(b > 0 || bdir >= 0);
+       if (adir < 0) {
+               a--;
+               adir = 1;
+       } else if (adir > 0)
+               adir = 1;
+       if (bdir < 0) {
+               b--;
+               bdir = 1;
+       } else if (bdir > 0)
+               bdir = 1;
+       return a < b || (a == b && adir < bdir);
+}
+
+/* Return 1 if max is nearer to best than min */
+static int approx_nearer(int min, int mindir,
+                        int best, int bestdir,
+                        int max, int maxdir)
+{
+       int dmin, dmindir;
+       int dmax, dmaxdir;
+       approx_sub(best, bestdir, min, mindir, &dmin, &dmindir);
+       approx_sub(max, maxdir, best, bestdir, &dmax, &dmaxdir);
+       return approx_lt(dmax, dmaxdir, dmin, dmindir);
 }
 
 static inline int hw_is_mask(int var)
@@ -52,48 +85,48 @@ static inline int hw_is_interval(int var)
 }
 
 static inline mask_t *hw_param_mask(snd_pcm_hw_params_t *params,
-                                 unsigned int var)
+                                 snd_pcm_hw_param_t var)
 {
        assert(hw_is_mask(var));
        return (mask_t*)&params->masks[var - SND_PCM_HW_PARAM_FIRST_MASK];
 }
 
 static inline interval_t *hw_param_interval(snd_pcm_hw_params_t *params,
-                                         unsigned int var)
+                                         snd_pcm_hw_param_t var)
 {
        assert(hw_is_interval(var));
        return &params->intervals[var - SND_PCM_HW_PARAM_FIRST_INTERVAL];
 }
 
 static inline const mask_t *hw_param_mask_c(const snd_pcm_hw_params_t *params,
-                                         unsigned int var)
+                                         snd_pcm_hw_param_t var)
 {
        return (const mask_t *)hw_param_mask((snd_pcm_hw_params_t*) params, var);
 }
 
 static inline const interval_t *hw_param_interval_c(const snd_pcm_hw_params_t *params,
-                                                 unsigned int var)
+                                                   snd_pcm_hw_param_t var)
 {
        return (const interval_t *)hw_param_interval((snd_pcm_hw_params_t*) params, var);
 }
 
-void _snd_pcm_hw_param_any(snd_pcm_hw_params_t *params, unsigned int var)
+void _snd_pcm_hw_param_any(snd_pcm_hw_params_t *params, snd_pcm_hw_param_t var)
 {
        if (hw_is_mask(var)) {
-               mask_all(hw_param_mask(params, var));
-               params->appl_cmask |= 1 << var;
+               mask_any(hw_param_mask(params, var));
+               params->cmask |= 1 << var;
                return;
        }
        if (hw_is_interval(var)) {
-               interval_all(hw_param_interval(params, var));
-               params->appl_cmask |= 1 << var;
+               interval_any(hw_param_interval(params, var));
+               params->cmask |= 1 << var;
                return;
        }
        assert(0);
 }
 
 int snd_pcm_hw_param_any(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
-                        unsigned int var)
+                        snd_pcm_hw_param_t var)
 {
        _snd_pcm_hw_param_any(params, var);
        return snd_pcm_hw_refine(pcm, params);
@@ -105,9 +138,6 @@ void _snd_pcm_hw_params_any(snd_pcm_hw_params_t *params)
        memset(params, 0, sizeof(*params));
        for (k = 0; k <= SND_PCM_HW_PARAM_LAST; k++)
                _snd_pcm_hw_param_any(params, k);
-       interval_setreal(hw_param_interval(params, SND_PCM_HW_PARAM_RATE));
-       interval_setreal(hw_param_interval(params, SND_PCM_HW_PARAM_FRAGMENT_LENGTH));
-       interval_setreal(hw_param_interval(params, SND_PCM_HW_PARAM_BUFFER_LENGTH));
        params->info = ~0U;
 }
 
@@ -122,18 +152,22 @@ int snd_pcm_hw_params_any(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
    defined by PARAMS. Return -EINVAL otherwise
 */
 int snd_pcm_hw_param_value(const snd_pcm_hw_params_t *params,
-                           unsigned int var)
+                          snd_pcm_hw_param_t var, int *dir)
 {
        if (hw_is_mask(var)) {
                const mask_t *mask = hw_param_mask_c(params, var);
                if (!mask_single(mask))
                        return -EINVAL;
+               if (dir)
+                       *dir = 0;
                return mask_value(mask);
        }
        if (hw_is_interval(var)) {
                const interval_t *i = hw_param_interval_c(params, var);
                if (!interval_single(i))
                        return -EINVAL;
+               if (dir)
+                       *dir = i->openmin;
                return interval_value(i);
        }
        assert(0);
@@ -142,13 +176,18 @@ int snd_pcm_hw_param_value(const snd_pcm_hw_params_t *params,
 
 /* Return the minimum value for field PAR. */
 unsigned int snd_pcm_hw_param_value_min(const snd_pcm_hw_params_t *params,
-                                        unsigned int var)
+                                       snd_pcm_hw_param_t var, int *dir)
 {
        if (hw_is_mask(var)) {
+               if (dir)
+                       *dir = 0;
                return mask_min(hw_param_mask_c(params, var));
        }
        if (hw_is_interval(var)) {
-               return interval_min(hw_param_interval_c(params, var));
+               const interval_t *i = hw_param_interval_c(params, var);
+               if (dir)
+                       *dir = i->openmin;
+               return interval_min(i);
        }
        assert(0);
        return -EINVAL;
@@ -156,13 +195,18 @@ unsigned int snd_pcm_hw_param_value_min(const snd_pcm_hw_params_t *params,
 
 /* Return the maximum value for field PAR. */
 unsigned int snd_pcm_hw_param_value_max(const snd_pcm_hw_params_t *params,
-                                        unsigned int var)
+                                       snd_pcm_hw_param_t var, int *dir)
 {
        if (hw_is_mask(var)) {
+               if (dir)
+                       *dir = 0;
                return mask_max(hw_param_mask_c(params, var));
        }
        if (hw_is_interval(var)) {
-               return interval_max(hw_param_interval_c(params, var));
+               const interval_t *i = hw_param_interval_c(params, var);
+               if (dir)
+                       *dir = - (int) i->openmax;
+               return interval_max(i);
        }
        assert(0);
        return -EINVAL;
@@ -172,7 +216,7 @@ unsigned int snd_pcm_hw_param_value_max(const snd_pcm_hw_params_t *params,
    This function can be called only for SND_PCM_HW_PARAM_ACCESS,
    SND_PCM_HW_PARAM_FORMAT, SND_PCM_HW_PARAM_SUBFORMAT. */
 const mask_t *snd_pcm_hw_param_value_mask(const snd_pcm_hw_params_t *params,
-                                          unsigned int var)
+                                          snd_pcm_hw_param_t var)
 {
        assert(hw_is_mask(var));
        return hw_param_mask_c(params, var);
@@ -182,17 +226,58 @@ const mask_t *snd_pcm_hw_param_value_mask(const snd_pcm_hw_params_t *params,
    This function cannot be called for SND_PCM_HW_PARAM_ACCESS,
    SND_PCM_HW_PARAM_FORMAT, SND_PCM_HW_PARAM_SUBFORMAT. */
 const interval_t *snd_pcm_hw_param_value_interval(const snd_pcm_hw_params_t *params,
-                                                  unsigned int var)
+                                                 snd_pcm_hw_param_t var)
 {
        assert(hw_is_interval(var));
        return hw_param_interval_c(params, var);
 }
 
-
 /* --- Refinement functions --- */
 
-int _snd_pcm_hw_param_first(snd_pcm_hw_params_t *params, int hw,
-                           unsigned int var)
+int _snd_pcm_hw_param_refine_interval(snd_pcm_hw_params_t *params,
+                                     snd_pcm_hw_param_t var,
+                                     const interval_t *val)
+{
+       int changed;
+       assert(hw_is_interval(var));
+       changed = interval_refine(hw_param_interval(params, var), val);
+       if (changed)
+               params->cmask |= 1 << var;
+       return changed;
+}
+
+int _snd_pcm_hw_param_setinteger(snd_pcm_hw_params_t *params,
+                                snd_pcm_hw_param_t var)
+{
+       int changed;
+       assert(hw_is_interval(var));
+       changed = interval_setinteger(hw_param_interval(params, var));
+       if (changed)
+               params->cmask |= 1 << var;
+       return changed;
+}
+       
+/* Inside configuration space defined by PARAMS remove from PAR all 
+   non integer values. Reduce configuration space accordingly.
+   Return -EINVAL if the configuration space is empty
+*/
+int snd_pcm_hw_param_setinteger(snd_pcm_t *pcm, 
+                               snd_pcm_hw_params_t *params,
+                               snd_pcm_hw_param_t var)
+{
+       int changed = _snd_pcm_hw_param_setinteger(params, var);
+       if (changed < 0)
+               return changed;
+       if (changed) {
+               int err = snd_pcm_hw_refine(pcm, params);
+               if (err < 0)
+                       return err;
+       }
+       return 0;
+}
+
+int _snd_pcm_hw_param_first(snd_pcm_hw_params_t *params,
+                           snd_pcm_hw_param_t var)
 {
        int changed;
        if (hw_is_mask(var))
@@ -203,12 +288,8 @@ int _snd_pcm_hw_param_first(snd_pcm_hw_params_t *params, int hw,
                assert(0);
                return -EINVAL;
        }
-       if (changed) {
-               if (hw)
-                       params->hw_cmask |= 1 << var;
-               else
-                       params->appl_cmask |= 1 << var;
-       }
+       if (changed)
+               params->cmask |= 1 << var;
        return changed;
 }
 
@@ -218,20 +299,21 @@ int _snd_pcm_hw_param_first(snd_pcm_hw_params_t *params, int hw,
    Return the minimum.
 */
 int snd_pcm_hw_param_first(snd_pcm_t *pcm, 
-                          snd_pcm_hw_params_t *params, unsigned int var)
+                          snd_pcm_hw_params_t *params, 
+                          snd_pcm_hw_param_t var, int *dir)
 {
-       int changed = _snd_pcm_hw_param_first(params, 0, var);
+       int changed = _snd_pcm_hw_param_first(params, var);
        if (changed < 0)
                return changed;
        if (changed) {
                int err = snd_pcm_hw_refine(pcm, params);
                assert(err >= 0);
        }
-       return snd_pcm_hw_param_value(params, var);
+       return snd_pcm_hw_param_value(params, var, dir);
 }
 
-int _snd_pcm_hw_param_last(snd_pcm_hw_params_t *params, int hw,
-                          unsigned int var)
+int _snd_pcm_hw_param_last(snd_pcm_hw_params_t *params,
+                          snd_pcm_hw_param_t var)
 {
        int changed;
        if (hw_is_mask(var))
@@ -242,12 +324,8 @@ int _snd_pcm_hw_param_last(snd_pcm_hw_params_t *params, int hw,
                assert(0);
                return -EINVAL;
        }
-       if (changed) {
-               if (hw)
-                       params->hw_cmask |= 1 << var;
-               else
-                       params->appl_cmask |= 1 << var;
-       }
+       if (changed)
+               params->cmask |= 1 << var;
        return changed;
 }
 
@@ -257,36 +335,44 @@ int _snd_pcm_hw_param_last(snd_pcm_hw_params_t *params, int hw,
    Return the maximum.
 */
 int snd_pcm_hw_param_last(snd_pcm_t *pcm, 
-                         snd_pcm_hw_params_t *params, unsigned int var)
+                         snd_pcm_hw_params_t *params,
+                         snd_pcm_hw_param_t var, int *dir)
 {
-       int changed = _snd_pcm_hw_param_last(params, 0, var);
+       int changed = _snd_pcm_hw_param_last(params, var);
        if (changed < 0)
                return changed;
        if (changed) {
                int err = snd_pcm_hw_refine(pcm, params);
                assert(err >= 0);
        }
-       return snd_pcm_hw_param_value(params, var);
+       return snd_pcm_hw_param_value(params, var, dir);
 }
 
-int _snd_pcm_hw_param_min(snd_pcm_hw_params_t *params, int hw,
-                         unsigned int var, unsigned int val)
+int _snd_pcm_hw_param_min(snd_pcm_hw_params_t *params,
+                         snd_pcm_hw_param_t var, unsigned int val, int dir)
 {
        int changed;
+       int open = 0;
+       if (dir) {
+               if (dir > 0) {
+                       open = 1;
+               } else if (dir < 0) {
+                       if (val > 0) {
+                               open = 1;
+                               val--;
+                       }
+               }
+       }
        if (hw_is_mask(var))
-               changed = mask_refine_min(hw_param_mask(params, var), val);
+               changed = mask_refine_min(hw_param_mask(params, var), val + !!open);
        else if (hw_is_interval(var))
-               changed = interval_refine_min(hw_param_interval(params, var), val);
+               changed = interval_refine_min(hw_param_interval(params, var), val, open);
        else {
                assert(0);
                return -EINVAL;
        }
-       if (changed) {
-               if (hw)
-                       params->hw_cmask |= 1 << var;
-               else
-                       params->appl_cmask |= 1 << var;
-       }
+       if (changed)
+               params->cmask |= 1 << var;
        return changed;
 }
 
@@ -295,9 +381,9 @@ int _snd_pcm_hw_param_min(snd_pcm_hw_params_t *params, int hw,
    Return new minimum or -EINVAL if the configuration space is empty
 */
 int snd_pcm_hw_param_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
-                         unsigned int var, unsigned int val)
+                         snd_pcm_hw_param_t var, unsigned int val, int *dir)
 {
-       int changed = _snd_pcm_hw_param_min(params, 0, var, val);
+       int changed = _snd_pcm_hw_param_min(params, var, val, dir ? *dir : 0);
        if (changed < 0)
                return changed;
        if (changed) {
@@ -305,39 +391,49 @@ int snd_pcm_hw_param_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
                if (err < 0)
                        return err;
        }
-       return snd_pcm_hw_param_value_min(params, var);
+       return snd_pcm_hw_param_value_min(params, var, dir);
 }
 
 int snd_pcm_hw_param_min_try(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
-                            unsigned int var, unsigned int val)
+                            snd_pcm_hw_param_t var,
+                            unsigned int val, int *dir)
 {
        snd_pcm_hw_params_t save;
        int err;
        save = *params;
-       err = snd_pcm_hw_param_min(pcm, params, var, val);
+       err = snd_pcm_hw_param_min(pcm, params, var, val, dir);
        if (err < 0)
                *params = save;
        return err;
 }
 
-int _snd_pcm_hw_param_max(snd_pcm_hw_params_t *params, int hw,
-                          unsigned int var, unsigned int val)
+int _snd_pcm_hw_param_max(snd_pcm_hw_params_t *params,
+                          snd_pcm_hw_param_t var, unsigned int val, int dir)
 {
        int changed;
-       if (hw_is_mask(var))
-               changed = mask_refine_max(hw_param_mask(params, var), val);
-       else if (hw_is_interval(var))
-               changed = interval_refine_max(hw_param_interval(params, var), val);
+       int open = 0;
+       if (dir) {
+               if (dir < 0) {
+                       open = 1;
+               } else if (dir > 0) {
+                       open = 1;
+                       val++;
+               }
+       }
+       if (hw_is_mask(var)) {
+               if (val == 0 && open) {
+                       mask_none(hw_param_mask(params, var));
+                       changed = -EINVAL;
+               } else
+                       changed = mask_refine_max(hw_param_mask(params, var), val - !!open);
+       } else if (hw_is_interval(var))
+               changed = interval_refine_max(hw_param_interval(params, var), val, open);
        else {
                assert(0);
                return -EINVAL;
        }
-       if (changed) {
-               if (hw)
-                       params->hw_cmask |= 1 << var;
-               else
-                       params->appl_cmask |= 1 << var;
-       }
+       if (changed)
+               params->cmask |= 1 << var;
        return changed;
 }
 
@@ -346,9 +442,9 @@ int _snd_pcm_hw_param_max(snd_pcm_hw_params_t *params, int hw,
    Return new maximum or -EINVAL if the configuration space is empty
 */
 int snd_pcm_hw_param_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
-                         unsigned int var, unsigned int val)
+                         snd_pcm_hw_param_t var, unsigned int val, int *dir)
 {
-       int changed = _snd_pcm_hw_param_max(params, 0, var, val);
+       int changed = _snd_pcm_hw_param_max(params, var, val, dir ? *dir : 0);
        if (changed < 0)
                return changed;
        if (changed) {
@@ -356,46 +452,72 @@ int snd_pcm_hw_param_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
                if (err < 0)
                        return err;
        }
-       return snd_pcm_hw_param_value_max(params, var);
+       return snd_pcm_hw_param_value_max(params, var, dir);
 }
 
 int snd_pcm_hw_param_max_try(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
-                            unsigned int var, unsigned int val)
+                            snd_pcm_hw_param_t var,
+                            unsigned int val, int *dir)
 {
        snd_pcm_hw_params_t save;
        int err;
        save = *params;
-       err = snd_pcm_hw_param_max(pcm, params, var, val);
+       err = snd_pcm_hw_param_max(pcm, params, var, val, dir);
        if (err < 0)
                *params = save;
        return err;
 }
 
-int _snd_pcm_hw_param_minmax(snd_pcm_hw_params_t *params, int hw,
-                             unsigned int var,
-                             unsigned int min, unsigned int max)
+int _snd_pcm_hw_param_minmax(snd_pcm_hw_params_t *params,
+                            snd_pcm_hw_param_t var,
+                            unsigned int min, int mindir,
+                            unsigned int max, int maxdir)
 {
        int changed, c1, c2;
+       int openmin = 0, openmax = 0;
+       if (mindir) {
+               if (mindir > 0) {
+                       openmin = 1;
+               } else if (mindir < 0) {
+                       if (min > 0) {
+                               openmin = 1;
+                               min--;
+                       }
+               }
+       }
+       if (maxdir) {
+               if (maxdir < 0) {
+                       openmax = 1;
+               } else if (maxdir > 0) {
+                       openmax = 1;
+                       max++;
+               }
+       }
        if (hw_is_mask(var)) {
                mask_t *mask = hw_param_mask(params, var);
-               c1 = mask_refine_min(mask, min);
-               if (c1 < 0)
-                       changed = c1;
-               else {
-                       c2 = mask_refine_max(mask, max);
-                       if (c2 < 0)
-                               changed = c2;
-                       else
-                               changed = (c1 || c2);
+               if (max == 0 && openmax) {
+                       mask_none(mask);
+                       changed = -EINVAL;
+               } else {
+                       c1 = mask_refine_min(mask, min + !!openmin);
+                       if (c1 < 0)
+                               changed = c1;
+                       else {
+                               c2 = mask_refine_max(mask, max - !!openmax);
+                               if (c2 < 0)
+                                       changed = c2;
+                               else
+                                       changed = (c1 || c2);
+                       }
                }
        }
        else if (hw_is_interval(var)) {
                interval_t *i = hw_param_interval(params, var);
-               c1 = interval_refine_min(i, min);
+               c1 = interval_refine_min(i, min, openmin);
                if (c1 < 0)
                        changed = c1;
                else {
-                       c2 = interval_refine_max(i, max);
+                       c2 = interval_refine_max(i, max, openmax);
                        if (c2 < 0)
                                changed = c2;
                        else
@@ -405,12 +527,8 @@ int _snd_pcm_hw_param_minmax(snd_pcm_hw_params_t *params, int hw,
                assert(0);
                return -EINVAL;
        }
-       if (changed) {
-               if (hw)
-                       params->hw_cmask |= 1 << var;
-               else
-                       params->appl_cmask |= 1 << var;
-       }
+       if (changed)
+               params->cmask |= 1 << var;
        return changed;
 }
 
@@ -419,10 +537,13 @@ int _snd_pcm_hw_param_minmax(snd_pcm_hw_params_t *params, int hw,
    Return 0 or -EINVAL if the configuration space is empty
 */
 int snd_pcm_hw_param_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
-                            unsigned int var,
-                            unsigned int min, unsigned int max)
+                           snd_pcm_hw_param_t var,
+                           unsigned int *min, int *mindir,
+                           unsigned int *max, int *maxdir)
 {
-       int changed = _snd_pcm_hw_param_minmax(params, 0, var, min, max);
+       int changed = _snd_pcm_hw_param_minmax(params, var, 
+                                              *min, mindir ? *mindir : 0,
+                                              *max, maxdir ? *maxdir : 0);
        if (changed < 0)
                return changed;
        if (changed) {
@@ -430,51 +551,82 @@ int snd_pcm_hw_param_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
                if (err < 0)
                        return err;
        }
+       *min = snd_pcm_hw_param_value_min(params, var, mindir);
+       *max = snd_pcm_hw_param_value_max(params, var, maxdir);
        return 0;
 }
 
 int snd_pcm_hw_param_minmax_try(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
-                               unsigned int var,
-                               unsigned int min, unsigned int max)
+                               snd_pcm_hw_param_t var,
+                               unsigned int *min, int *mindir,
+                               unsigned int *max, int *maxdir)
 {
        snd_pcm_hw_params_t save;
        int err;
        save = *params;
-       err = snd_pcm_hw_param_minmax(pcm, params, var, min, max);
+       err = snd_pcm_hw_param_minmax(pcm, params, var,
+                                     min, mindir, 
+                                     max, maxdir);
        if (err < 0)
                *params = save;
        return err;
 }
 
-int _snd_pcm_hw_param_set(snd_pcm_hw_params_t *params, int hw,
-                          unsigned int var, unsigned int val)
+int _snd_pcm_hw_param_set(snd_pcm_hw_params_t *params,
+                         snd_pcm_hw_param_t var, unsigned int val, int dir)
 {
        int changed;
-       if (hw_is_mask(var))
-               changed = mask_refine_set(hw_param_mask(params, var), val);
-       else if (hw_is_interval(var))
-               changed = interval_refine_set(hw_param_interval(params, var), val);
-       else {
+       if (hw_is_mask(var)) {
+               mask_t *m = hw_param_mask(params, var);
+               if (val == 0 && dir < 0) {
+                       changed = -EINVAL;
+                       mask_none(m);
+               } else {
+                       if (dir > 0)
+                               val++;
+                       else if (dir < 0)
+                               val--;
+                       changed = mask_refine_set(hw_param_mask(params, var), val);
+               }
+       } else if (hw_is_interval(var)) {
+               interval_t *i = hw_param_interval(params, var);
+               if (val == 0 && dir < 0) {
+                       changed = -EINVAL;
+                       interval_none(i);
+               } else if (dir == 0)
+                       changed = interval_refine_set(i, val);
+               else {
+                       interval_t t;
+                       t.openmin = 1;
+                       t.openmax = 1;
+                       t.empty = 0;
+                       t.integer = 0;
+                       if (dir < 0) {
+                               t.min = val - 1;
+                               t.max = val;
+                       } else {
+                               t.min = val;
+                               t.max = val+1;
+                       }
+                       changed = interval_refine(i, &t);
+               }
+       } else {
                assert(0);
                return -EINVAL;
        }
-       if (changed) {
-               if (hw)
-                       params->hw_cmask |= 1 << var;
-               else
-                       params->appl_cmask |= 1 << var;
-       }
+       if (changed)
+               params->cmask |= 1 << var;
        return changed;
 }
 
 /* Inside configuration space defined by PARAMS remove from PAR all 
-   values < VAL and >= VAL +1. Reduce configuration space accordingly.
+   values != VAL. Reduce configuration space accordingly.
    Return VAL or -EINVAL if the configuration space is empty
 */
 int snd_pcm_hw_param_set(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
-                         unsigned int var, unsigned int val)
+                        snd_pcm_hw_param_t var, unsigned int val, int dir)
 {
-       int changed = _snd_pcm_hw_param_set(params, 0, var, val);
+       int changed = _snd_pcm_hw_param_set(params, var, val, dir);
        if (changed < 0)
                return changed;
        if (changed) {
@@ -482,33 +634,29 @@ int snd_pcm_hw_param_set(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
                if (err < 0)
                        return err;
        }
-       return snd_pcm_hw_param_value(params, var);
+       return snd_pcm_hw_param_value(params, var, 0);
 }
 
 int snd_pcm_hw_param_set_try(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
-                            unsigned int var, unsigned int val)
+                            snd_pcm_hw_param_t var, unsigned int val, int dir)
 {
        snd_pcm_hw_params_t save;
        int err;
        save = *params;
-       err = snd_pcm_hw_param_set(pcm, params, var, val);
+       err = snd_pcm_hw_param_set(pcm, params, var, val, dir);
        if (err < 0)
                *params = save;
        return err;
 }
 
-int _snd_pcm_hw_param_mask(snd_pcm_hw_params_t *params, int hw,
-                           unsigned int var, const mask_t *val)
+int _snd_pcm_hw_param_mask(snd_pcm_hw_params_t *params,
+                           snd_pcm_hw_param_t var, const mask_t *val)
 {
        int changed;
        assert(hw_is_mask(var));
        changed = mask_refine(hw_param_mask(params, var), val);
-       if (changed) {
-               if (hw)
-                       params->hw_cmask |= 1 << var;
-               else
-                       params->appl_cmask |= 1 << var;
-       }
+       if (changed)
+               params->cmask |= 1 << var;
        return changed;
 }
 
@@ -520,9 +668,9 @@ int _snd_pcm_hw_param_mask(snd_pcm_hw_params_t *params, int hw,
    if the configuration space is empty
 */
 int snd_pcm_hw_param_mask(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
-                         unsigned int var, const mask_t *val)
+                         snd_pcm_hw_param_t var, const mask_t *val)
 {
-       int changed = _snd_pcm_hw_param_mask(params, 0, var, val);
+       int changed = _snd_pcm_hw_param_mask(params, var, val);
        if (changed < 0)
                return changed;
        if (changed) {
@@ -534,7 +682,7 @@ int snd_pcm_hw_param_mask(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
 }
 
 int snd_pcm_hw_param_mask_try(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
-                             unsigned int var, const mask_t *val)
+                             snd_pcm_hw_param_t var, const mask_t *val)
 {
        snd_pcm_hw_params_t save;
        int err;
@@ -552,93 +700,180 @@ int snd_pcm_hw_param_mask_try(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
    Return the value found.
  */
 int snd_pcm_hw_param_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
-                          unsigned int var, unsigned int val)
+                         snd_pcm_hw_param_t var, unsigned int best, int *dir)
 {
        snd_pcm_hw_params_t save;
        int v;
-       unsigned int max1 = val, min2 = add(val, 1);
-       unsigned int hw_cmask;
+       unsigned int saved_min;
+       int last = 0;
+       unsigned int cmask;
+       int min, max;
+       int mindir, maxdir;
+       int valdir = dir ? *dir : 0;
+       /* FIXME */
+       if (best > INT_MAX)
+               best = INT_MAX;
+       min = max = best;
+       mindir = maxdir = valdir;
+       if (maxdir > 0)
+               maxdir = 0;
+       else if (maxdir == 0)
+               maxdir = -1;
+       else {
+               maxdir = 1;
+               max--;
+       }
        save = *params;
-       v = snd_pcm_hw_param_max(pcm, params, var, max1);
-       if (v >= 0) {
-               int v1;
+       saved_min = min;
+       min = snd_pcm_hw_param_min(pcm, params, var, min, &mindir);
+       if (min >= 0) {
                snd_pcm_hw_params_t params1;
-               if (val == (unsigned int)v)
+               if (max < 0)
+                       goto _end;
+               if ((unsigned int)min = saved_min && mindir == valdir)
                        goto _end;
                params1 = save;
-               v1 = snd_pcm_hw_param_min(pcm, &params1, var, min2);
-               if (v1 < 0)
+               max = snd_pcm_hw_param_max(pcm, &params1, var, max, &maxdir);
+               if (max < 0)
                        goto _end;
-               if (val - v > v1 - val) {
+               if (approx_nearer(max, maxdir, best, valdir, min, mindir)) {
                        *params = params1;
-                       v = v1;
+                       last = 1;
                }
        } else {
                *params = save;
-               v = snd_pcm_hw_param_min(pcm, params, var, min2);
-               assert(v >= 0);
+               max = snd_pcm_hw_param_max(pcm, params, var, max, &maxdir);
+               assert(max >= 0);
+               last = 1;
        }
  _end:
-       hw_cmask = params->hw_cmask;
-       v = snd_pcm_hw_param_set(pcm, params, var, v);
-       params->hw_cmask |= hw_cmask;
+       cmask = params->cmask;
+       if (last)
+               v = snd_pcm_hw_param_last(pcm, params, var, dir);
+       else
+               v = snd_pcm_hw_param_first(pcm, params, var, dir);
+       params->cmask |= cmask;
        assert(v >= 0);
        return v;
 }
 
 /* Inside configuration space defined by PARAMS set PAR to the available value
-   nearest to VAL after OLD (values less than VAL are returned first).
+   nearest to BEST after VAL (on equal difference values less than BEST are
+   returned first).
    Reduce configuration space accordingly.
    This function cannot be called for SND_PCM_HW_PARAM_ACCESS,
    SND_PCM_HW_PARAM_FORMAT, SND_PCM_HW_PARAM_SUBFORMAT.
    Return the value found.
  */
 int snd_pcm_hw_param_next(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
-                          unsigned int var, unsigned int val,
-                          unsigned int old)
+                         snd_pcm_hw_param_t var, 
+                         unsigned int best, int bestdir,
+                         unsigned int val, int *dir)
 {
        snd_pcm_hw_params_t save;
        int v;
-       unsigned int max1, min2;
-       int diff = old - val;
-       if (diff < 0) {
-               max1 = sub(old, 1);
-               min2 = add(val, -diff);
+       int last = 0;
+       unsigned int cmask;
+       int min, max;
+       int mindir, maxdir;
+       int diff, diffdir;
+       int valdir = dir ? *dir : 0;
+       /* FIXME */
+       if (best > INT_MAX)
+               best = INT_MAX;
+       approx_sub(val, valdir, best, bestdir, &diff, &diffdir);
+       if (diff < 0 || (diff == 0 && diffdir < 0)) {
+               min = best - diff;
+               mindir = bestdir - diffdir;
+               max = val;
+               maxdir = bestdir - 1;
        } else {
-               max1 = sub(val, diff + 1);
-               min2 = add(old, 1);
-       }
+               min = val;
+               mindir = bestdir + 1;
+               max = best + diff;
+               maxdir = bestdir + diffdir + 1;
+       }
+       min += mindir / 2;
+       mindir %= 2;
+       max += maxdir / 2;
+       maxdir %= 2;
        save = *params;
-       v = snd_pcm_hw_param_max(pcm, params, var, max1);
-       if (v >= 0) {
-               int v1;
+       if (min >= 0 &&
+           (min = snd_pcm_hw_param_min(pcm, params, var, min, &mindir)) >= 0) {
                snd_pcm_hw_params_t params1;
-               if (val == (unsigned int)v)
+               if (max < 0)
                        goto _end;
                params1 = save;
-               v1 = snd_pcm_hw_param_min(pcm, &params1, var, min2);
-               if (v1 < 0)
+               max = snd_pcm_hw_param_max(pcm, &params1, var, max, &maxdir);
+               if (max < 0)
                        goto _end;
-               if (val - v > v1 - val) {
+               if (approx_nearer(max, maxdir, best, bestdir, min, mindir)) {
                        *params = params1;
-                       v = v1;
+                       last = 1;
                }
        } else {
+               if (max < 0)
+                       return -EINVAL;
                *params = save;
-               v = snd_pcm_hw_param_min(pcm, params, var, min2);
-               if (v < 0)
-                       return v;
+               max = snd_pcm_hw_param_max(pcm, params, var, max, &maxdir);
+               if (max < 0)
+                       return max;
+               last = 1;
        }
  _end:
-       v = snd_pcm_hw_param_set(pcm, params, var, v);
+       cmask = params->cmask;
+       if (last)
+               v = snd_pcm_hw_param_last(pcm, params, var, dir);
+       else
+               v = snd_pcm_hw_param_first(pcm, params, var, dir);
+       params->cmask |= cmask;
+       assert(v >= 0);
        return v;
 }
 
+void snd_pcm_hw_param_near_minmax(snd_pcm_t *pcm,
+                                 snd_pcm_hw_params_t *params,
+                                 snd_pcm_hw_param_t var,
+                                 unsigned int min, int *mindir,
+                                 unsigned int max, int *maxdir)
+{
+       snd_pcm_hw_params_t tmp;
+       int err;
+       if (!approx_lt(min, *mindir, max, *maxdir)) {
+               snd_pcm_hw_param_near(pcm, params, var, min, mindir);
+               return;
+       }
+       tmp = *params;
+       min = snd_pcm_hw_param_near(pcm, &tmp, var, min, mindir);
+       if (approx_lt(min, *mindir, max, *maxdir)) {
+               tmp = *params;
+               max = snd_pcm_hw_param_near(pcm, &tmp, var, max, maxdir);
+       } else {
+               max = min;
+               *maxdir = *mindir;
+       }
+       err = snd_pcm_hw_param_minmax(pcm, params, var, &min, mindir,
+                                     &max, maxdir);
+       assert(err >= 0);
+}
+
+void snd_pcm_hw_param_near_copy(snd_pcm_t *pcm,
+                               snd_pcm_hw_params_t *params,
+                               snd_pcm_hw_param_t var,
+                               const snd_pcm_hw_params_t *src)
+{
+       unsigned int min, max;
+       int mindir, maxdir;
+       min = snd_pcm_hw_param_value_min(src, var, &mindir);
+       max = snd_pcm_hw_param_value_max(src, var, &maxdir);
+       snd_pcm_hw_param_near_minmax(pcm, params, var,
+                                    min, &mindir, max, &maxdir);
+}
 
 /* ---- end of refinement functions ---- */
 
 int snd_pcm_hw_param_empty(const snd_pcm_hw_params_t *params,
-                           unsigned int var)
+                           snd_pcm_hw_param_t var)
 {
        if (hw_is_mask(var))
                return mask_empty(hw_param_mask_c(params, var));
@@ -648,6 +883,35 @@ int snd_pcm_hw_param_empty(const snd_pcm_hw_params_t *params,
        return -EINVAL;
 }
 
+int snd_pcm_hw_param_always_eq(const snd_pcm_hw_params_t *params,
+                              snd_pcm_hw_param_t var,
+                              const snd_pcm_hw_params_t *params1)
+{
+       if (hw_is_mask(var))
+               return mask_always_eq(hw_param_mask_c(params, var),
+                                     hw_param_mask_c(params1, var));
+       if (hw_is_interval(var))
+               return interval_always_eq(hw_param_interval_c(params, var),
+                                         hw_param_interval_c(params1, var));
+       assert(0);
+       return -EINVAL;
+}
+
+int snd_pcm_hw_param_never_eq(const snd_pcm_hw_params_t *params,
+                             snd_pcm_hw_param_t var,
+                             const snd_pcm_hw_params_t *params1)
+{
+       if (hw_is_mask(var))
+               return mask_never_eq(hw_param_mask_c(params, var),
+                                     hw_param_mask_c(params1, var));
+       if (hw_is_interval(var))
+               return interval_never_eq(hw_param_interval_c(params, var),
+                                        hw_param_interval_c(params1, var));
+       assert(0);
+       return -EINVAL;
+}
+
+
 /* Return rate numerator/denumerator obtainable for configuration space defined
    by PARAMS */
 int snd_pcm_hw_params_info_rate(const snd_pcm_hw_params_t *params,
@@ -692,43 +956,48 @@ int snd_pcm_hw_params_info_fifo_size(const snd_pcm_hw_params_t *params)
    first subformat
    min channels
    min rate
-   min fragment size
-   max fragments
+   min period time
+   max buffer size
+   min tick time
 */
 void snd_pcm_hw_params_choose(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
 {
        int err;
-       unsigned int hw_cmask = params->hw_cmask;
+       unsigned int cmask = params->cmask;
 
-       err = snd_pcm_hw_param_first(pcm, params, SND_PCM_HW_PARAM_ACCESS);
+       err = snd_pcm_hw_param_first(pcm, params, SND_PCM_HW_PARAM_ACCESS, 0);
        assert(err >= 0);
-       hw_cmask |= params->hw_cmask;
+       cmask |= params->cmask;
 
-       err = snd_pcm_hw_param_first(pcm, params, SND_PCM_HW_PARAM_FORMAT);
+       err = snd_pcm_hw_param_first(pcm, params, SND_PCM_HW_PARAM_FORMAT, 0);
        assert(err >= 0);
-       hw_cmask |= params->hw_cmask;
+       cmask |= params->cmask;
 
-       err = snd_pcm_hw_param_first(pcm, params, SND_PCM_HW_PARAM_SUBFORMAT);
+       err = snd_pcm_hw_param_first(pcm, params, SND_PCM_HW_PARAM_SUBFORMAT, 0);
        assert(err >= 0);
-       hw_cmask |= params->hw_cmask;
+       cmask |= params->cmask;
 
-       err = snd_pcm_hw_param_first(pcm, params, SND_PCM_HW_PARAM_CHANNELS);
+       err = snd_pcm_hw_param_first(pcm, params, SND_PCM_HW_PARAM_CHANNELS, 0);
        assert(err >= 0);
-       hw_cmask |= params->hw_cmask;
+       cmask |= params->cmask;
 
-       err = snd_pcm_hw_param_first(pcm, params, SND_PCM_HW_PARAM_RATE);
+       err = snd_pcm_hw_param_first(pcm, params, SND_PCM_HW_PARAM_RATE, 0);
        assert(err >= 0);
-       hw_cmask |= params->hw_cmask;
+       cmask |= params->cmask;
 
-       err = snd_pcm_hw_param_first(pcm, params, SND_PCM_HW_PARAM_FRAGMENT_SIZE);
+       err = snd_pcm_hw_param_first(pcm, params, SND_PCM_HW_PARAM_PERIOD_TIME, 0);
        assert(err >= 0);
-       hw_cmask |= params->hw_cmask;
+       cmask |= params->cmask;
 
-       err = snd_pcm_hw_param_last(pcm, params, SND_PCM_HW_PARAM_FRAGMENTS);
+       err = snd_pcm_hw_param_last(pcm, params, SND_PCM_HW_PARAM_BUFFER_SIZE, 0);
        assert(err >= 0);
-       hw_cmask |= params->hw_cmask;
+       cmask |= params->cmask;
 
-       params->hw_cmask = hw_cmask;
+       err = snd_pcm_hw_param_first(pcm, params, SND_PCM_HW_PARAM_TICK_TIME, 0);
+       assert(err >= 0);
+       cmask |= params->cmask;
+
+       params->cmask = cmask;
 }
 
 /* Strategies */
@@ -740,7 +1009,7 @@ struct _snd_pcm_hw_strategy {
                            const snd_pcm_hw_strategy_t *strategy);
        int (*next_value)(snd_pcm_hw_params_t *params,
                          unsigned int param,
-                         int value,
+                         int value, int *dir,
                          snd_pcm_t *pcm,
                          const snd_pcm_hw_strategy_t *strategy);
        int (*min_badness)(const snd_pcm_hw_params_t *params,
@@ -759,7 +1028,7 @@ struct _snd_pcm_hw_strategy_simple {
        unsigned int order;
        int (*next_value)(snd_pcm_hw_params_t *params,
                          unsigned int param,
-                         int value,
+                         int value, int *dir,
                          snd_pcm_t *pcm,
                          const snd_pcm_hw_strategy_simple_t *par);
        unsigned int (*min_badness)(const snd_pcm_hw_params_t *params,
@@ -782,7 +1051,7 @@ typedef struct _snd_pcm_hw_strategy_simple_choices {
 } snd_pcm_hw_strategy_simple_choices_t;
 
 int snd_pcm_hw_param_test(const snd_pcm_hw_params_t *params,
-                          unsigned int var, unsigned int val)
+                          snd_pcm_hw_param_t var, unsigned int val)
 {
        if (hw_is_mask(var)) {
                const mask_t *mask = hw_param_mask_c(params, var);
@@ -797,7 +1066,7 @@ int snd_pcm_hw_param_test(const snd_pcm_hw_params_t *params,
 }
 
 unsigned int snd_pcm_hw_param_count(const snd_pcm_hw_params_t *params,
-                                    unsigned int var)
+                                    snd_pcm_hw_param_t var)
 {
        if (hw_is_mask(var)) {
                const mask_t *mask = hw_param_mask_c(params, var);
@@ -811,9 +1080,9 @@ unsigned int snd_pcm_hw_param_count(const snd_pcm_hw_params_t *params,
        return 0;
 }
 
-int _snd_pcm_hw_param_refine(snd_pcm_hw_params_t *params, int hw,
-                            unsigned int var,
-                            const snd_pcm_hw_params_t *src)
+int snd_pcm_hw_param_refine(snd_pcm_hw_params_t *params,
+                           snd_pcm_hw_param_t var,
+                           const snd_pcm_hw_params_t *src)
 {
        int changed = 0;
        if (hw_is_mask(var)) {
@@ -826,16 +1095,12 @@ int _snd_pcm_hw_param_refine(snd_pcm_hw_params_t *params, int hw,
                changed = interval_refine(d, s);
        } else
                assert(0);
-       if (changed) {
-               if (hw)
-                       params->hw_cmask |= 1 << var;
-               else
-                       params->appl_cmask |= 1 << var;
-       }
+       if (changed)
+               params->cmask |= 1 << var;
        return changed;
 }
                             
-void snd_pcm_hw_param_copy(snd_pcm_hw_params_t *params, unsigned int var,
+void snd_pcm_hw_param_copy(snd_pcm_hw_params_t *params, snd_pcm_hw_param_t var,
                            const snd_pcm_hw_params_t *src)
 {
        if (hw_is_mask(var)) {
@@ -852,7 +1117,7 @@ void snd_pcm_hw_param_copy(snd_pcm_hw_params_t *params, unsigned int var,
 }
 
 void snd_pcm_hw_param_dump(const snd_pcm_hw_params_t *params,
-                          unsigned int var, FILE *fp)
+                          snd_pcm_hw_param_t var, FILE *fp)
 {
        static const char *(*funcs[])(unsigned int k) = {
                [SND_PCM_HW_PARAM_ACCESS] = snd_pcm_access_name,
@@ -905,7 +1170,7 @@ int snd_pcm_hw_params_strategy(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
 {
        snd_pcm_hw_params_t best_params;
        int var;
-       int value;
+       int value, dir;
        unsigned int best_badness;
        int badness = strategy->min_badness(params, badness_max, pcm, strategy);
        snd_pcm_hw_params_t params1;
@@ -923,14 +1188,14 @@ int snd_pcm_hw_params_strategy(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
        best_badness = UINT_MAX;
        value = -1;
        while (1) {
-               unsigned int hw_cmask;
+               unsigned int cmask;
                params1 = *params;
-               value = strategy->next_value(&params1, var, value, pcm, strategy);
+               value = strategy->next_value(&params1, var, value, &dir, pcm, strategy);
                if (value < 0)
                        break;
-               hw_cmask = params1.hw_cmask;
+               cmask = params1.cmask;
                badness = snd_pcm_hw_params_strategy(pcm, &params1, strategy, badness_min, badness_max);
-               params1.hw_cmask |= hw_cmask;
+               params1.cmask |= cmask;
                if (badness >= 0) {
                        if ((unsigned int) badness <= badness_min) {
                                *params = params1;
@@ -963,7 +1228,7 @@ int snd_pcm_hw_strategy_simple_choose_param(const snd_pcm_hw_params_t *params,
                                         snd_pcm_t *pcm ATTRIBUTE_UNUSED,
                                         const snd_pcm_hw_strategy_t *strategy)
 {
-       unsigned int var;
+       snd_pcm_hw_param_t var;
        int best_var = -1;
        const snd_pcm_hw_strategy_simple_t *pars = strategy->private;
        unsigned int min_choices = UINT_MAX;
@@ -989,14 +1254,14 @@ int snd_pcm_hw_strategy_simple_choose_param(const snd_pcm_hw_params_t *params,
 }
 
 int snd_pcm_hw_strategy_simple_next_value(snd_pcm_hw_params_t *params,
-                                      unsigned int var,
-                                      int value,
-                                      snd_pcm_t *pcm,
-                                      const snd_pcm_hw_strategy_t *strategy)
+                                         snd_pcm_hw_param_t var,
+                                         int value, int *dir,
+                                         snd_pcm_t *pcm,
+                                         const snd_pcm_hw_strategy_t *strategy)
 {
        const snd_pcm_hw_strategy_simple_t *pars = strategy->private;
        assert(pars[var].valid);
-       return pars[var].next_value(params, var, value, pcm, &pars[var]);
+       return pars[var].next_value(params, var, value, dir, pcm, &pars[var]);
 }
 
 
@@ -1005,7 +1270,7 @@ int snd_pcm_hw_strategy_simple_min_badness(const snd_pcm_hw_params_t *params,
                                        snd_pcm_t *pcm,
                                        const snd_pcm_hw_strategy_t *strategy)
 {
-       unsigned int var;
+       snd_pcm_hw_param_t var;
        unsigned int badness = 0;
        const snd_pcm_hw_strategy_simple_t *pars = strategy->private;
        for (var = 0; var <= SND_PCM_HW_PARAM_LAST; ++var) {
@@ -1028,13 +1293,13 @@ void snd_pcm_hw_strategy_simple_near_free(snd_pcm_hw_strategy_simple_t *par)
 }
 
 unsigned int snd_pcm_hw_strategy_simple_near_min_badness(const snd_pcm_hw_params_t *params,
-                                                     unsigned int var,
+                                                     snd_pcm_hw_param_t var,
                                                      snd_pcm_t *pcm,
                                                      const snd_pcm_hw_strategy_simple_t *par)
 {
        const snd_pcm_hw_strategy_simple_near_t *p = par->private;
        snd_pcm_hw_params_t params1 = *params;
-       int value = snd_pcm_hw_param_near(pcm, &params1, var, p->best);
+       int value = snd_pcm_hw_param_near(pcm, &params1, var, p->best, 0);
        int diff;
        assert(value >= 0);
        diff = p->best - value;
@@ -1044,16 +1309,17 @@ unsigned int snd_pcm_hw_strategy_simple_near_min_badness(const snd_pcm_hw_params
 }
        
 int snd_pcm_hw_strategy_simple_near_next_value(snd_pcm_hw_params_t *params,
-                                           unsigned int var,
-                                           int value,
-                                           snd_pcm_t *pcm,
-                                           const snd_pcm_hw_strategy_simple_t *par)
+                                              snd_pcm_hw_param_t var,
+                                              int value, int *dir,
+                                              snd_pcm_t *pcm,
+                                              const snd_pcm_hw_strategy_simple_t *par)
 {
        const snd_pcm_hw_strategy_simple_near_t *p = par->private;
-       if (value < 0) 
-               return snd_pcm_hw_param_near(pcm, params, var, p->best);
-       else
-               return snd_pcm_hw_param_next(pcm, params, var, p->best, value);
+       if (value < 0) {
+               *dir = 0;
+               return snd_pcm_hw_param_near(pcm, params, var, p->best, dir);
+       } else
+               return snd_pcm_hw_param_next(pcm, params, var, p->best, 0, value, dir);
 }
 
 void snd_pcm_hw_strategy_simple_choices_free(snd_pcm_hw_strategy_simple_t *par)
@@ -1064,7 +1330,7 @@ void snd_pcm_hw_strategy_simple_choices_free(snd_pcm_hw_strategy_simple_t *par)
 }
 
 unsigned int snd_pcm_hw_strategy_simple_choices_min_badness(const snd_pcm_hw_params_t *params,
-                                                        unsigned int var,
+                                                        snd_pcm_hw_param_t var,
                                                         snd_pcm_t *pcm ATTRIBUTE_UNUSED,
                                                         const snd_pcm_hw_strategy_simple_t *par)
 {
@@ -1079,10 +1345,10 @@ unsigned int snd_pcm_hw_strategy_simple_choices_min_badness(const snd_pcm_hw_par
 }
        
 int snd_pcm_hw_strategy_simple_choices_next_value(snd_pcm_hw_params_t *params,
-                                              unsigned int var,
-                                              int value,
-                                              snd_pcm_t *pcm,
-                                              const snd_pcm_hw_strategy_simple_t *par)
+                                                 snd_pcm_hw_param_t var,
+                                                 int value, int *dir,
+                                                 snd_pcm_t *pcm,
+                                                 const snd_pcm_hw_strategy_simple_t *par)
 {
        const snd_pcm_hw_strategy_simple_choices_t *p = par->private;
        unsigned int k = 0;
@@ -1098,11 +1364,12 @@ int snd_pcm_hw_strategy_simple_choices_next_value(snd_pcm_hw_params_t *params,
                unsigned int v = p->choices[k].value;
                if (snd_pcm_hw_param_test(params, var, v)) {
                        snd_pcm_hw_params_t save = *params;
-                       int err = snd_pcm_hw_param_set(pcm, params, var, v);
+                       int err = snd_pcm_hw_param_set(pcm, params, var, v, 0);
                        if (err < 0) {
                                *params = save;
                                continue;
                        }
+                       *dir = 0;
                        return v;
                }
        }
@@ -1145,7 +1412,7 @@ int snd_pcm_hw_strategy_simple(snd_pcm_hw_strategy_t **strategyp,
 
 int snd_pcm_hw_strategy_simple_near(snd_pcm_hw_strategy_t *strategy,
                                 int order,
-                                unsigned int var,
+                                snd_pcm_hw_param_t var,
                                 unsigned int best,
                                 unsigned int mul)
 {
@@ -1171,7 +1438,7 @@ int snd_pcm_hw_strategy_simple_near(snd_pcm_hw_strategy_t *strategy,
 
 int snd_pcm_hw_strategy_simple_choices(snd_pcm_hw_strategy_t *strategy,
                                    int order,
-                                   unsigned int var,
+                                   snd_pcm_hw_param_t var,
                                    unsigned int count,
                                    snd_pcm_hw_strategy_simple_choices_list_t *choices)
 {
@@ -1201,7 +1468,7 @@ int snd_pcm_hw_params_try_explain_failure1(snd_pcm_t *pcm,
                                           unsigned int depth,
                                           FILE *fp)
 {
-       unsigned int var;
+       snd_pcm_hw_param_t var;
        snd_pcm_hw_params_t i;
        if (depth < 1)
                return -ENOENT;
@@ -1229,7 +1496,7 @@ int snd_pcm_hw_params_try_explain_failure(snd_pcm_t *pcm,
 {
        snd_pcm_hw_params_t i, any;
        int err;
-       unsigned int var;
+       snd_pcm_hw_param_t var;
        int done = 0;
        assert(pcm && fail);
        for (var = 0; var <= SND_PCM_HW_PARAM_LAST; var++) {
@@ -1268,35 +1535,39 @@ struct _snd_pcm_hw_rule {
 int snd_pcm_hw_rule_mul(snd_pcm_hw_params_t *params,
                        snd_pcm_hw_rule_t *rule)
 {
-       return interval_mul(hw_param_interval(params, rule->var),
-                           hw_param_interval(params, rule->deps[0]),
-                           hw_param_interval(params, rule->deps[1]));
+       interval_t t;
+       interval_mul(hw_param_interval_c(params, rule->deps[0]),
+                    hw_param_interval_c(params, rule->deps[1]), &t);
+       return interval_refine(hw_param_interval(params, rule->var), &t);
 }
 
 int snd_pcm_hw_rule_div(snd_pcm_hw_params_t *params,
                        snd_pcm_hw_rule_t *rule)
 {
-       return interval_div(hw_param_interval(params, rule->var),
-                           hw_param_interval(params, rule->deps[0]),
-                           hw_param_interval(params, rule->deps[1]));
+       interval_t t;
+       interval_div(hw_param_interval_c(params, rule->deps[0]),
+                    hw_param_interval_c(params, rule->deps[1]), &t);
+       return interval_refine(hw_param_interval(params, rule->var), &t);
 }
 
 int snd_pcm_hw_rule_muldivk(snd_pcm_hw_params_t *params,
                            snd_pcm_hw_rule_t *rule)
 {
-       return interval_muldivk(hw_param_interval(params, rule->var),
-                               (unsigned long) rule->private,
-                               hw_param_interval(params, rule->deps[0]),
-                               hw_param_interval(params, rule->deps[1]));
+       interval_t t;
+       interval_muldivk(hw_param_interval_c(params, rule->deps[0]),
+                        hw_param_interval_c(params, rule->deps[1]),
+                        (unsigned long) rule->private, &t);
+       return interval_refine(hw_param_interval(params, rule->var), &t);
 }
 
 int snd_pcm_hw_rule_mulkdiv(snd_pcm_hw_params_t *params,
                            snd_pcm_hw_rule_t *rule)
 {
-       return interval_mulkdiv(hw_param_interval(params, rule->var),
-                               (unsigned long) rule->private,
-                               hw_param_interval(params, rule->deps[0]),
-                               hw_param_interval(params, rule->deps[1]));
+       interval_t t;
+       interval_mulkdiv(hw_param_interval_c(params, rule->deps[0]),
+                        (unsigned long) rule->private,
+                        hw_param_interval_c(params, rule->deps[1]), &t);
+       return interval_refine(hw_param_interval(params, rule->var), &t);
 }
 
 int snd_pcm_hw_rule_format(snd_pcm_hw_params_t *params,
@@ -1346,12 +1617,12 @@ int snd_pcm_hw_rule_sample_bits(snd_pcm_hw_params_t *params,
                if (max < (unsigned)bits)
                        max = bits;
        }
-       c = interval_refine_min(i, min);
+       c = interval_refine_min(i, min, 0);
        if (c < 0)
                return c;
        if (c)
                changed = 1;
-       c = interval_refine_max(i, max);
+       c = interval_refine_max(i, max, 0);
        if (c < 0)
                return c;
        if (c)
@@ -1389,8 +1660,8 @@ static snd_pcm_hw_rule_t refine_rules[] = {
        {
                var: SND_PCM_HW_PARAM_FRAME_BITS, 
                func: snd_pcm_hw_rule_mulkdiv,
-               deps: { SND_PCM_HW_PARAM_FRAGMENT_BYTES,
-                       SND_PCM_HW_PARAM_FRAGMENT_SIZE, -1 },
+               deps: { SND_PCM_HW_PARAM_PERIOD_BYTES,
+                       SND_PCM_HW_PARAM_PERIOD_SIZE, -1 },
                private: (void*) 8,
        },
        {
@@ -1410,50 +1681,50 @@ static snd_pcm_hw_rule_t refine_rules[] = {
        {
                var: SND_PCM_HW_PARAM_RATE, 
                func: snd_pcm_hw_rule_mulkdiv,
-               deps: { SND_PCM_HW_PARAM_FRAGMENT_SIZE,
-                       SND_PCM_HW_PARAM_FRAGMENT_LENGTH, -1 },
+               deps: { SND_PCM_HW_PARAM_PERIOD_SIZE,
+                       SND_PCM_HW_PARAM_PERIOD_TIME, -1 },
                private: (void*) 1000000,
        },
        {
                var: SND_PCM_HW_PARAM_RATE, 
                func: snd_pcm_hw_rule_mulkdiv,
                deps: { SND_PCM_HW_PARAM_BUFFER_SIZE,
-                       SND_PCM_HW_PARAM_BUFFER_LENGTH, -1 },
+                       SND_PCM_HW_PARAM_BUFFER_TIME, -1 },
                private: (void*) 1000000,
        },
        {
-               var: SND_PCM_HW_PARAM_FRAGMENTS, 
+               var: SND_PCM_HW_PARAM_PERIODS, 
                func: snd_pcm_hw_rule_div,
                deps: { SND_PCM_HW_PARAM_BUFFER_SIZE,
-                       SND_PCM_HW_PARAM_FRAGMENT_SIZE, -1 },
+                       SND_PCM_HW_PARAM_PERIOD_SIZE, -1 },
                private: 0,
        },
        {
-               var: SND_PCM_HW_PARAM_FRAGMENT_SIZE, 
+               var: SND_PCM_HW_PARAM_PERIOD_SIZE, 
                func: snd_pcm_hw_rule_div,
                deps: { SND_PCM_HW_PARAM_BUFFER_SIZE,
-                       SND_PCM_HW_PARAM_FRAGMENTS, -1 },
+                       SND_PCM_HW_PARAM_PERIODS, -1 },
                private: 0,
        },
        {
-               var: SND_PCM_HW_PARAM_FRAGMENT_SIZE, 
+               var: SND_PCM_HW_PARAM_PERIOD_SIZE, 
                func: snd_pcm_hw_rule_mulkdiv,
-               deps: { SND_PCM_HW_PARAM_FRAGMENT_BYTES,
+               deps: { SND_PCM_HW_PARAM_PERIOD_BYTES,
                        SND_PCM_HW_PARAM_FRAME_BITS, -1 },
                private: (void*) 8,
        },
        {
-               var: SND_PCM_HW_PARAM_FRAGMENT_SIZE, 
+               var: SND_PCM_HW_PARAM_PERIOD_SIZE, 
                func: snd_pcm_hw_rule_muldivk,
-               deps: { SND_PCM_HW_PARAM_FRAGMENT_LENGTH,
+               deps: { SND_PCM_HW_PARAM_PERIOD_TIME,
                        SND_PCM_HW_PARAM_RATE, -1 },
                private: (void*) 1000000,
        },
        {
                var: SND_PCM_HW_PARAM_BUFFER_SIZE, 
                func: snd_pcm_hw_rule_mul,
-               deps: { SND_PCM_HW_PARAM_FRAGMENT_SIZE,
-                       SND_PCM_HW_PARAM_FRAGMENTS, -1 },
+               deps: { SND_PCM_HW_PARAM_PERIOD_SIZE,
+                       SND_PCM_HW_PARAM_PERIODS, -1 },
                private: 0,
        },
        {
@@ -1466,14 +1737,14 @@ static snd_pcm_hw_rule_t refine_rules[] = {
        {
                var: SND_PCM_HW_PARAM_BUFFER_SIZE, 
                func: snd_pcm_hw_rule_muldivk,
-               deps: { SND_PCM_HW_PARAM_BUFFER_LENGTH,
+               deps: { SND_PCM_HW_PARAM_BUFFER_TIME,
                        SND_PCM_HW_PARAM_RATE, -1 },
                private: (void*) 1000000,
        },
        {
-               var: SND_PCM_HW_PARAM_FRAGMENT_BYTES, 
+               var: SND_PCM_HW_PARAM_PERIOD_BYTES, 
                func: snd_pcm_hw_rule_muldivk,
-               deps: { SND_PCM_HW_PARAM_FRAGMENT_SIZE,
+               deps: { SND_PCM_HW_PARAM_PERIOD_SIZE,
                        SND_PCM_HW_PARAM_FRAME_BITS, -1 },
                private: (void*) 8,
        },
@@ -1485,14 +1756,14 @@ static snd_pcm_hw_rule_t refine_rules[] = {
                private: (void*) 8,
        },
        {
-               var: SND_PCM_HW_PARAM_FRAGMENT_LENGTH
+               var: SND_PCM_HW_PARAM_PERIOD_TIME
                func: snd_pcm_hw_rule_mulkdiv,
-               deps: { SND_PCM_HW_PARAM_FRAGMENT_SIZE,
+               deps: { SND_PCM_HW_PARAM_PERIOD_SIZE,
                        SND_PCM_HW_PARAM_RATE, -1 },
                private: (void*) 1000000,
        },
        {
-               var: SND_PCM_HW_PARAM_BUFFER_LENGTH
+               var: SND_PCM_HW_PARAM_BUFFER_TIME
                func: snd_pcm_hw_rule_mulkdiv,
                deps: { SND_PCM_HW_PARAM_BUFFER_SIZE,
                        SND_PCM_HW_PARAM_RATE, -1 },
@@ -1515,49 +1786,53 @@ static mask_t refine_masks[SND_PCM_HW_PARAM_LAST_MASK - SND_PCM_HW_PARAM_FIRST_M
 };
 
 static interval_t refine_intervals[SND_PCM_HW_PARAM_LAST_INTERVAL - SND_PCM_HW_PARAM_FIRST_INTERVAL + 1] = {
-       [SND_PCM_HW_PARAM_CHANNELS - SND_PCM_HW_PARAM_FIRST_INTERVAL] = {
+       [SND_PCM_HW_PARAM_SAMPLE_BITS - SND_PCM_HW_PARAM_FIRST_INTERVAL] = {
                min: 1, max: UINT_MAX,
-               openmin: 0, openmax: 0, real: 0, empty: 0,
+               openmin: 0, openmax: 0, integer: 1, empty: 0,
        },
-       [SND_PCM_HW_PARAM_RATE - SND_PCM_HW_PARAM_FIRST_INTERVAL] = {
+       [SND_PCM_HW_PARAM_FRAME_BITS - SND_PCM_HW_PARAM_FIRST_INTERVAL] = {
                min: 1, max: UINT_MAX,
-               openmin: 0, openmax: 0, real: 0, empty: 0,
+               openmin: 0, openmax: 0, integer: 1, empty: 0,
        },
-       [SND_PCM_HW_PARAM_FRAGMENT_LENGTH - SND_PCM_HW_PARAM_FIRST_INTERVAL] = {
+       [SND_PCM_HW_PARAM_CHANNELS - SND_PCM_HW_PARAM_FIRST_INTERVAL] = {
                min: 1, max: UINT_MAX,
-               openmin: 0, openmax: 0, real: 0, empty: 0,
+               openmin: 0, openmax: 0, integer: 1, empty: 0,
        },
-       [SND_PCM_HW_PARAM_FRAGMENT_SIZE - SND_PCM_HW_PARAM_FIRST_INTERVAL] = {
+       [SND_PCM_HW_PARAM_RATE - SND_PCM_HW_PARAM_FIRST_INTERVAL] = {
                min: 1, max: UINT_MAX,
-               openmin: 0, openmax: 0, real: 0, empty: 0,
+               openmin: 0, openmax: 0, integer: 0, empty: 0,
        },
-       [SND_PCM_HW_PARAM_FRAGMENTS - SND_PCM_HW_PARAM_FIRST_INTERVAL] = {
-               min: 1, max: UINT_MAX,
-               openmin: 0, openmax: 0, real: 0, empty: 0,
+       [SND_PCM_HW_PARAM_PERIOD_TIME - SND_PCM_HW_PARAM_FIRST_INTERVAL] = {
+               min: 0, max: UINT_MAX,
+               openmin: 0, openmax: 0, integer: 0, empty: 0,
        },
-       [SND_PCM_HW_PARAM_BUFFER_LENGTH - SND_PCM_HW_PARAM_FIRST_INTERVAL] = {
-               min: 1, max: UINT_MAX,
-               openmin: 0, openmax: 0, real: 0, empty: 0,
+       [SND_PCM_HW_PARAM_PERIOD_SIZE - SND_PCM_HW_PARAM_FIRST_INTERVAL] = {
+               min: 0, max: UINT_MAX,
+               openmin: 0, openmax: 0, integer: 0, empty: 0,
        },
-       [SND_PCM_HW_PARAM_BUFFER_SIZE - SND_PCM_HW_PARAM_FIRST_INTERVAL] = {
-               min: 1, max: UINT_MAX,
-               openmin: 0, openmax: 0, real: 0, empty: 0,
+       [SND_PCM_HW_PARAM_PERIOD_BYTES - SND_PCM_HW_PARAM_FIRST_INTERVAL] = {
+               min: 0, max: UINT_MAX,
+               openmin: 0, openmax: 0, integer: 0, empty: 0,
        },
-       [SND_PCM_HW_PARAM_SAMPLE_BITS - SND_PCM_HW_PARAM_FIRST_INTERVAL] = {
-               min: 1, max: UINT_MAX,
-               openmin: 0, openmax: 0, real: 0, empty: 0,
+       [SND_PCM_HW_PARAM_PERIODS - SND_PCM_HW_PARAM_FIRST_INTERVAL] = {
+               min: 0, max: UINT_MAX,
+               openmin: 0, openmax: 0, integer: 0, empty: 0,
        },
-       [SND_PCM_HW_PARAM_FRAME_BITS - SND_PCM_HW_PARAM_FIRST_INTERVAL] = {
+       [SND_PCM_HW_PARAM_BUFFER_TIME - SND_PCM_HW_PARAM_FIRST_INTERVAL] = {
                min: 1, max: UINT_MAX,
-               openmin: 0, openmax: 0, real: 0, empty: 0,
+               openmin: 0, openmax: 0, integer: 0, empty: 0,
        },
-       [SND_PCM_HW_PARAM_FRAGMENT_BYTES - SND_PCM_HW_PARAM_FIRST_INTERVAL] = {
+       [SND_PCM_HW_PARAM_BUFFER_SIZE - SND_PCM_HW_PARAM_FIRST_INTERVAL] = {
                min: 1, max: UINT_MAX,
-               openmin: 0, openmax: 0, real: 0, empty: 0,
+               openmin: 0, openmax: 0, integer: 1, empty: 0,
        },
        [SND_PCM_HW_PARAM_BUFFER_BYTES - SND_PCM_HW_PARAM_FIRST_INTERVAL] = {
                min: 1, max: UINT_MAX,
-               openmin: 0, openmax: 0, real: 0, empty: 0,
+               openmin: 0, openmax: 0, integer: 1, empty: 0,
+       },
+       [SND_PCM_HW_PARAM_TICK_TIME - SND_PCM_HW_PARAM_FIRST_INTERVAL] = {
+               min: 0, max: UINT_MAX,
+               openmin: 0, openmax: 0, integer: 0, empty: 0,
        },
 };
 
@@ -1573,7 +1848,7 @@ int _snd_pcm_hw_refine(snd_pcm_hw_params_t *params)
        int err, changed;
 
        for (k = SND_PCM_HW_PARAM_FIRST_MASK; k <= SND_PCM_HW_PARAM_LAST_MASK; k++) {
-               if (!params->appl_cmask & (1 << k))
+               if (!(params->cmask & (1 << k)))
                        continue;
                err = mask_refine(hw_param_mask(params, k),
                                  &refine_masks[k - SND_PCM_HW_PARAM_FIRST_MASK]);
@@ -1582,7 +1857,7 @@ int _snd_pcm_hw_refine(snd_pcm_hw_params_t *params)
        }
 
        for (k = SND_PCM_HW_PARAM_FIRST_INTERVAL; k <= SND_PCM_HW_PARAM_LAST_INTERVAL; k++) {
-               if (!params->appl_cmask & (1 << k))
+               if (!(params->cmask & (1 << k)))
                        continue;
                err = interval_refine(hw_param_interval(params, k),
                                      &refine_intervals[k - SND_PCM_HW_PARAM_FIRST_INTERVAL]);
@@ -1593,9 +1868,8 @@ int _snd_pcm_hw_refine(snd_pcm_hw_params_t *params)
        for (k = 0; k < RULES; k++)
                rstamps[k] = 0;
        for (k = 0; k <= SND_PCM_HW_PARAM_LAST; k++)
-               vstamps[k] = (params->appl_cmask & (1 << k)) ? 1 : 0;
-       params->appl_cmask = 0;
-       params->hw_cmask = 0;
+               vstamps[k] = (params->cmask & (1 << k)) ? 1 : 0;
+       params->cmask = 0;
        changed = 1;
        while (changed) {
                changed = 0;
@@ -1626,7 +1900,7 @@ int _snd_pcm_hw_refine(snd_pcm_hw_params_t *params)
 #endif
                        rstamps[k] = stamp;
                        if (err && r->var >= 0) {
-                               params->hw_cmask |= 1 << r->var;
+                               params->cmask |= 1 << r->var;
                                vstamps[r->var] = stamp;
                                changed = 1;
                        }
@@ -1651,111 +1925,66 @@ int _snd_pcm_hw_refine(snd_pcm_hw_params_t *params)
        return 0;
 }
 
-int snd_pcm_hw_refine2(snd_pcm_hw_params_t *params,
-                      snd_pcm_hw_params_t *sparams,
-                      int (*func)(snd_pcm_t *slave,
-                                  snd_pcm_hw_params_t *sparams),
-                      snd_pcm_t *slave, 
-                      unsigned int links)
-{
-       unsigned int k;
-       int err, error = 0;
-       unsigned int client_from_slave = ~0U;
-       unsigned int client_refine = ~0U;
-       unsigned int slave_from_client = ~0U;
-       unsigned int slave_refine = ~0U;
-       unsigned int hw_cmask = params->hw_cmask;
-
-       while (client_from_slave || client_refine) {
-               for (k = 0; k <= SND_PCM_HW_PARAM_LAST; ++k) {
-                       int changed;
-                       if (!(links & (1 << k)))
-                               continue;
-                       if (!(client_from_slave & (1 << k)))
-                               continue;
-                       changed = _snd_pcm_hw_param_refine(params, 1, k, sparams);
-                       if (changed) {
-                               hw_cmask |= 1 << k;
-                               slave_from_client |= 1 << k;
-                               client_refine |= 1 << k;
-                       }
-                       if (changed < 0)
-                               error = changed;
-               }
-               client_from_slave = 0;
-               if (error)
-                       break;
-               if (client_refine) {
-                       params->appl_cmask = client_refine;
-                       client_refine = 0;
-                       err = _snd_pcm_hw_refine(params);
-                       hw_cmask |= params->hw_cmask;
-                       slave_from_client |= params->hw_cmask;
-                       if (err < 0) {
-                               error = err;
-                               break;
-                       }
-               }
-       
-               for (k = 0; k <= SND_PCM_HW_PARAM_LAST; ++k) {
-                       int changed;
-                       if (!(links & (1 << k)))
-                               continue;
-                       if (!(slave_from_client & (1 << k)))
-                               continue;
-                       changed = _snd_pcm_hw_param_refine(sparams, 1, k, params);
-                       if (changed) {
-                               slave_refine |= 1 << k;
-                               client_from_slave |= 1 << k;
-                       }
-                       if (changed < 0)
-                               error = changed;
-               }
-               slave_from_client = 0;
-               if (error)
-                       continue;
-               if (slave_refine) {
-                       sparams->appl_cmask = slave_refine;
-                       slave_refine = 0;
-                       error = func(slave, sparams);
-                       client_from_slave |= sparams->hw_cmask;
-               }
-       }
-       params->appl_cmask = 0;
-       params->hw_cmask = hw_cmask;
-       return error;
-}
-
-int snd_pcm_hw_params2(snd_pcm_hw_params_t *params,
-                      snd_pcm_hw_params_t *sparams,
-                      int (*func)(snd_pcm_t *slave,
-                                  snd_pcm_hw_params_t *sparams),
-                      snd_pcm_t *slave, 
-                      unsigned int links)
+int snd_pcm_hw_params_refine(snd_pcm_hw_params_t *params,
+                            unsigned int vars,
+                            const snd_pcm_hw_params_t *src)
 {
+       int changed, err = 0;
        unsigned int k;
-       int err;
        for (k = 0; k <= SND_PCM_HW_PARAM_LAST; ++k) {
-               int changed;
-               if (!(links & (1 << k)))
+               if (!(vars & (1 << k)) ||
+                   !((src->cmask & (1 << k))))
                        continue;
-               changed = _snd_pcm_hw_param_refine(sparams, 0, k, params);
+               changed = snd_pcm_hw_param_refine(params, k, src);
                if (changed < 0)
-                       return changed;
+                       err = changed;
        }
-       sparams->appl_cmask = ~0U;
-       err = func(slave, sparams);
-       if (err >= 0)
-               return err;
+       return err;
+}
 
-       for (k = 0; k <= SND_PCM_HW_PARAM_LAST; ++k) {
-               int changed;
-               if (!(links & (1 << k)))
-                       continue;
-               if (!(sparams->hw_cmask & (1 << k)))
-                       continue;
-               changed = _snd_pcm_hw_param_refine(params, 1, k, sparams);
+/* Accumulate to params->cmask */
+/* Reset sparams->cmask */
+int snd_pcm_generic_hw_link(snd_pcm_hw_params_t *params,
+                           snd_pcm_hw_params_t *sparams,
+                           snd_pcm_t *slave,
+                           unsigned long links)
+{
+       int err1, err = 0;
+       err = snd_pcm_hw_params_refine(sparams, links, params);
+       if (err >= 0) {
+               unsigned int cmask = sparams->cmask;
+               err = snd_pcm_hw_refine(slave, sparams);
+               sparams->cmask |= cmask;
+       }
+       err1 = snd_pcm_hw_params_refine(params, links, sparams);
+       if (err1 < 0)
+               err = err1;
+       sparams->cmask = 0;
+       return err;
+}
+
+int snd_pcm_hw_refine2(snd_pcm_hw_params_t *params,
+                      snd_pcm_hw_params_t *sparams,
+                      int (*func)(snd_pcm_hw_params_t *params,
+                                  snd_pcm_hw_params_t *sparams,
+                                  snd_pcm_t *slave,
+                                  unsigned long private),
+                      snd_pcm_t *slave,
+                      unsigned long private)
+{
+       int err = 0;
+       unsigned int cmask = 0;
+       while (params->cmask) {
+               err = func(params, sparams, slave, private);
+               cmask |= params->cmask;
+               if (err < 0)
+                       break;
+               err = _snd_pcm_hw_refine(params);
+               cmask |= params->cmask;
+               if (err < 0)
+                       break;
        }
+       params->cmask = cmask;
        return err;
 }
 
@@ -1764,10 +1993,10 @@ int snd_pcm_sw_params_current(snd_pcm_t *pcm, snd_pcm_sw_params_t *params)
        assert(pcm && params);
        assert(pcm->setup);
        params->start_mode = pcm->start_mode;
-       params->ready_mode = pcm->ready_mode;
        params->xrun_mode = pcm->xrun_mode;
-       params->silence_mode = pcm->silence_mode;
        params->tstamp_mode = pcm->tstamp_mode;
+       params->period_step = pcm->period_step;
+       params->sleep_min = pcm->sleep_min;
        params->avail_min = pcm->avail_min;
        params->xfer_align = pcm->xfer_align;
        params->silence_threshold = pcm->silence_threshold;
@@ -1781,31 +2010,31 @@ int snd_pcm_sw_params_default(snd_pcm_t *pcm, snd_pcm_sw_params_t *params)
        assert(pcm && params);
        assert(pcm->setup);
        params->start_mode = SND_PCM_START_DATA;
-       params->ready_mode = SND_PCM_READY_FRAGMENT;
-       params->xrun_mode = SND_PCM_XRUN_FRAGMENT;
-       params->silence_mode = SND_PCM_SILENCE_FRAGMENT;
+       params->xrun_mode = SND_PCM_XRUN_STOP;
        params->tstamp_mode = SND_PCM_TSTAMP_NONE;
-       params->avail_min = pcm->fragment_size;
-       params->xfer_align = pcm->fragment_size;
+       params->period_step = 1;
+       params->sleep_min = 0;
+       params->avail_min = pcm->period_size;
+       params->xfer_align = pcm->period_size;
        params->silence_threshold = 0;
        params->silence_size = 0;
        params->boundary = LONG_MAX - pcm->buffer_size * 2 - LONG_MAX % pcm->buffer_size;
        return 0;
 }
 
-int snd_pcm_sw_param_value(snd_pcm_sw_params_t *params, unsigned int var)
+int snd_pcm_sw_param_value(snd_pcm_sw_params_t *params, snd_pcm_sw_param_t var)
 {
        switch (var) {
        case SND_PCM_SW_PARAM_START_MODE:
                return params->start_mode;
-       case SND_PCM_SW_PARAM_READY_MODE:
-               return params->ready_mode;
        case SND_PCM_SW_PARAM_XRUN_MODE:
                return params->xrun_mode;
-       case SND_PCM_SW_PARAM_SILENCE_MODE:
-               return params->silence_mode;
        case SND_PCM_SW_PARAM_TSTAMP_MODE:
                return params->tstamp_mode;
+       case SND_PCM_SW_PARAM_PERIOD_STEP:
+               return params->period_step;
+       case SND_PCM_SW_PARAM_SLEEP_MIN:
+               return params->sleep_min;
        case SND_PCM_SW_PARAM_AVAIL_MIN:
                return params->avail_min;
        case SND_PCM_SW_PARAM_XFER_ALIGN:
@@ -1821,29 +2050,27 @@ int snd_pcm_sw_param_value(snd_pcm_sw_params_t *params, unsigned int var)
 }
 
 int snd_pcm_sw_param_set(snd_pcm_t *pcm, snd_pcm_sw_params_t *params,
-                        unsigned int var, unsigned int val)
+                        snd_pcm_sw_param_t var, unsigned int val)
 {
        switch (var) {
        case SND_PCM_SW_PARAM_START_MODE:
                assert(val <= SND_PCM_START_LAST);
                params->start_mode = val;
                break;
-       case SND_PCM_SW_PARAM_READY_MODE:
-               assert(val <= SND_PCM_READY_LAST);
-               params->ready_mode = val;
-               break;
        case SND_PCM_SW_PARAM_XRUN_MODE:
                assert(val <= SND_PCM_XRUN_LAST);
                params->xrun_mode = val;
                break;
-       case SND_PCM_SW_PARAM_SILENCE_MODE:
-               assert(val <= SND_PCM_SILENCE_LAST);
-               params->silence_mode = val;
-               break;
        case SND_PCM_SW_PARAM_TSTAMP_MODE:
                assert(val <= SND_PCM_TSTAMP_LAST);
                params->tstamp_mode = val;
                break;
+       case SND_PCM_SW_PARAM_PERIOD_STEP:
+               params->period_step = val;
+               break;
+       case SND_PCM_SW_PARAM_SLEEP_MIN:
+               params->sleep_min = val;
+               break;
        case SND_PCM_SW_PARAM_AVAIL_MIN:
                assert(val > 0);
                params->avail_min = val;
@@ -1868,25 +2095,17 @@ int snd_pcm_sw_param_set(snd_pcm_t *pcm, snd_pcm_sw_params_t *params,
 }
 
 int snd_pcm_sw_param_near(snd_pcm_t *pcm, snd_pcm_sw_params_t *params,
-                         unsigned int var, unsigned int val)
+                         snd_pcm_sw_param_t var, unsigned int val)
 {
        switch (var) {
        case SND_PCM_SW_PARAM_START_MODE:
                assert(val <= SND_PCM_START_LAST);
                params->start_mode = val;
                break;
-       case SND_PCM_SW_PARAM_READY_MODE:
-               assert(val <= SND_PCM_READY_LAST);
-               params->ready_mode = val;
-               break;
        case SND_PCM_SW_PARAM_XRUN_MODE:
                assert(val <= SND_PCM_XRUN_LAST);
                params->xrun_mode = val;
                break;
-       case SND_PCM_SW_PARAM_SILENCE_MODE:
-               assert(val <= SND_PCM_SILENCE_LAST);
-               params->silence_mode = val;
-               break;
        case SND_PCM_SW_PARAM_TSTAMP_MODE:
                assert(val <= SND_PCM_TSTAMP_LAST);
                params->tstamp_mode = val;
@@ -1896,9 +2115,15 @@ int snd_pcm_sw_param_near(snd_pcm_t *pcm, snd_pcm_sw_params_t *params,
                        val = pcm->min_align;
                params->avail_min = val;
                break;
+       case SND_PCM_SW_PARAM_PERIOD_STEP:
+               params->period_step = val;
+               break;
+       case SND_PCM_SW_PARAM_SLEEP_MIN:
+               params->sleep_min = val;
+               break;
        case SND_PCM_SW_PARAM_XFER_ALIGN:
        {
-               size_t r = val % pcm->min_align;
+               snd_pcm_uframes_t r = val % pcm->min_align;
                if (r >= (pcm->min_align + 1) / 2)
                        val += pcm->min_align - r;
                else
@@ -1926,24 +2151,24 @@ int snd_pcm_sw_param_near(snd_pcm_t *pcm, snd_pcm_sw_params_t *params,
 }
 
 void snd_pcm_sw_param_dump(const snd_pcm_sw_params_t *params,
-                          unsigned int var, FILE *fp)
+                          snd_pcm_sw_param_t var, FILE *fp)
 {
        switch (var) {
        case SND_PCM_SW_PARAM_START_MODE:
                fputs(snd_pcm_start_mode_name(params->start_mode), fp);
                break;
-       case SND_PCM_SW_PARAM_READY_MODE:
-               fputs(snd_pcm_ready_mode_name(params->ready_mode), fp);
-               break;
        case SND_PCM_SW_PARAM_XRUN_MODE:
                fputs(snd_pcm_xrun_mode_name(params->xrun_mode), fp);
                break;
-       case SND_PCM_SW_PARAM_SILENCE_MODE:
-               fputs(snd_pcm_silence_mode_name(params->silence_mode), fp);
-               break;
        case SND_PCM_SW_PARAM_TSTAMP_MODE:
                fputs(snd_pcm_tstamp_mode_name(params->tstamp_mode), fp);
                break;
+       case SND_PCM_SW_PARAM_PERIOD_STEP:
+               fprintf(fp, "%d", params->period_step);
+               break;
+       case SND_PCM_SW_PARAM_SLEEP_MIN:
+               fprintf(fp, "%d", params->sleep_min);
+               break;
        case SND_PCM_SW_PARAM_AVAIL_MIN:
                fprintf(fp, "%ld", (long) params->avail_min);
                break;
@@ -1975,12 +2200,8 @@ int snd_pcm_sw_params_dump(snd_pcm_sw_params_t *params, FILE *fp)
 
 int snd_pcm_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
 {
-       int err;
        assert(pcm && params);
-       params->hw_cmask = 0;
-       err = pcm->ops->hw_refine(pcm->op_arg, params);
-       params->appl_cmask = 0;
-       return err;
+       return pcm->ops->hw_refine(pcm->op_arg, params);
 }
 
 /* Install one of the configurations present in configuration
@@ -1991,8 +2212,8 @@ int snd_pcm_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
    first subformat
    min channels
    min rate
-   min fragment_size
-   max fragments
+   min period_size
+   max periods
    Return 0 on success or a negative number expressing the error.
 */
 int snd_pcm_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
@@ -2014,13 +2235,15 @@ int snd_pcm_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
                goto _mmap;
 
        pcm->setup = 1;
-       pcm->access = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_ACCESS);
-       pcm->format = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FORMAT);
-       pcm->subformat = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_SUBFORMAT);
-       pcm->channels = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_CHANNELS);
-       pcm->rate = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_RATE);
-       pcm->fragment_size = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FRAGMENT_SIZE);
-       pcm->fragments = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FRAGMENTS);
+       pcm->access = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_ACCESS, 0);
+       pcm->format = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FORMAT, 0);
+       pcm->subformat = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_SUBFORMAT, 0);
+       pcm->channels = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_CHANNELS, 0);
+       pcm->rate = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_RATE, 0);
+       pcm->period_time = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_PERIOD_TIME, 0);
+       pcm->period_size = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_PERIOD_SIZE, 0);
+       pcm->buffer_size = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_BUFFER_SIZE, 0);
+       pcm->tick_time = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_TICK_TIME, 0);
        pcm->bits_per_sample = snd_pcm_format_physical_width(pcm->format);
        pcm->bits_per_frame = pcm->bits_per_sample * pcm->channels;
        fb = pcm->bits_per_frame;
@@ -2030,7 +2253,6 @@ int snd_pcm_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
                min_align *= 2;
        }
        pcm->min_align = min_align;
-       pcm->buffer_size = pcm->fragment_size * pcm->fragments;
        
        pcm->info = params->info;
        pcm->msbits = params->msbits;
@@ -2066,10 +2288,10 @@ int snd_pcm_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t *params)
        if (err < 0)
                return err;
        pcm->start_mode = params->start_mode;
-       pcm->ready_mode = params->ready_mode;
        pcm->xrun_mode = params->xrun_mode;
-       pcm->silence_mode = params->silence_mode;
        pcm->tstamp_mode = params->tstamp_mode;
+       pcm->period_step = params->period_step;
+       pcm->sleep_min = params->sleep_min;
        pcm->avail_min = params->avail_min;
        pcm->xfer_align = params->xfer_align;
        pcm->silence_threshold = params->silence_threshold;
index 5255493d6be72bcdc53bb60382c73373ef723e86..9f7ba854987e0235ea5c12d1e973bed1a9331f41 100644 (file)
@@ -21,7 +21,7 @@
   
 #include "pcm_local.h"
 #include "pcm_plugin.h"
-
+#include "interval.h"
 
 typedef struct {
        snd_pcm_t *req_slave;
@@ -191,82 +191,37 @@ static int snd_pcm_plug_slave_format(int format, const mask_t *format_mask)
                             (1 << SND_PCM_FORMAT_A_LAW) | \
                             (1 << SND_PCM_FORMAT_IMA_ADPCM))
 
-static int snd_pcm_plug_hw_refine1(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
-                                  snd_pcm_hw_params_t *sparams)
+
+/* Accumulate to params->cmask */
+/* Reset sparams->cmask */
+static int snd_pcm_plug_hw_link(snd_pcm_hw_params_t *params,
+                               snd_pcm_hw_params_t *sparams,
+                               snd_pcm_t *slave,
+                               unsigned long private ATTRIBUTE_UNUSED)
 {
-       snd_pcm_plug_t *plug = pcm->private;
-       snd_pcm_t *slave = plug->req_slave;
-       int err;
+       int rate_always, channels_always, format_always, access_always;
+       int rate_never, channels_never, format_never, access_never;
+       unsigned int links = (SND_PCM_HW_PARBIT_PERIOD_TIME |
+                             SND_PCM_HW_PARBIT_TICK_TIME);
        const mask_t *format_mask, *sformat_mask;
-       unsigned int rate_min, rate_max, srate_min, srate_max;
-       unsigned int channels_min, channels_max, schannels_min, schannels_max;
+       mask_t *fmt_mask = alloca(mask_sizeof());
+       mask_t *sfmt_mask = alloca(mask_sizeof());
+       mask_t *access_mask = alloca(mask_sizeof());
+       int err;
        unsigned int format;
-       int same_rate, same_channels, same_format;
-       snd_pcm_hw_params_t tmp;
-       unsigned int links = (SND_PCM_HW_PARBIT_FRAGMENT_LENGTH |
-                             SND_PCM_HW_PARBIT_FRAGMENTS |
-                             SND_PCM_HW_PARBIT_BUFFER_LENGTH);
-       mask_t *tmp_mask = alloca(mask_sizeof());
-       mask_t *accplug_mask = alloca(mask_sizeof());
-       mask_t *mmap_mask = alloca(mask_sizeof());
-       mask_t *fmtplug_mask = alloca(mask_sizeof());
-       mask_load(accplug_mask, SND_PCM_ACCBIT_PLUGIN);
-       mask_load(mmap_mask, SND_PCM_ACCBIT_MMAP);
-       mask_load(fmtplug_mask, SND_PCM_FMTBIT_PLUG);
-       
-       err = _snd_pcm_hw_param_min(params, 1, SND_PCM_HW_PARAM_CHANNELS, 1);
-       if (err < 0)
-               return err;
-       err = _snd_pcm_hw_param_min(params, 1, SND_PCM_HW_PARAM_RATE, RATE_MIN);
-       if (err < 0)
-               return err;
-       err = _snd_pcm_hw_param_max(params, 1, SND_PCM_HW_PARAM_RATE, RATE_MAX);
-       if (err < 0)
-               return err;
-
-       _snd_pcm_hw_params_any(sparams);
-       err = snd_pcm_hw_refine2(params, sparams,
-                                snd_pcm_hw_refine, slave, links);
-       if (err < 0)
-               return err;
-       
-       rate_min = snd_pcm_hw_param_value_min(params, SND_PCM_HW_PARAM_RATE);
-       rate_max = snd_pcm_hw_param_value_max(params, SND_PCM_HW_PARAM_RATE);
-       tmp = *sparams;
-       srate_min = snd_pcm_hw_param_near(slave, &tmp,
-                                          SND_PCM_HW_PARAM_RATE, rate_min);
-       if (srate_min < rate_max) {
-               tmp = *sparams;
-               srate_max = snd_pcm_hw_param_near(slave, &tmp,
-                                                  SND_PCM_HW_PARAM_RATE, rate_max);
-       } else 
-               srate_max = srate_min;
-       err = snd_pcm_hw_param_minmax(slave, sparams,
-                                      SND_PCM_HW_PARAM_RATE,
-                                      srate_min, srate_max);
-       assert(err >= 0);
-
-       channels_min = snd_pcm_hw_param_value_min(params, SND_PCM_HW_PARAM_CHANNELS);
-       channels_max = snd_pcm_hw_param_value_max(params, SND_PCM_HW_PARAM_CHANNELS);
-       tmp = *sparams;
-       schannels_min = snd_pcm_hw_param_near(slave, &tmp,
-                                              SND_PCM_HW_PARAM_CHANNELS, channels_min);
-       if (schannels_min < channels_max) {
-               tmp = *sparams;
-               schannels_max = snd_pcm_hw_param_near(slave, &tmp,
-                                                      SND_PCM_HW_PARAM_CHANNELS, channels_max);
-       } else 
-               schannels_max = schannels_min;
-       err = snd_pcm_hw_param_minmax(slave, sparams,
-                                      SND_PCM_HW_PARAM_CHANNELS,
-                                      schannels_min, schannels_max);
-       assert(err >= 0);
-
+       unsigned int scmask = sparams->cmask;
+       snd_pcm_hw_param_near_copy(slave, sparams, SND_PCM_HW_PARAM_RATE,
+                                  params);
+       scmask |= sparams->cmask;
+       snd_pcm_hw_param_near_copy(slave, sparams, SND_PCM_HW_PARAM_CHANNELS,
+                                  params);
+       scmask |= sparams->cmask;
        format_mask = snd_pcm_hw_param_value_mask(params,
                                                   SND_PCM_HW_PARAM_FORMAT);
        sformat_mask = snd_pcm_hw_param_value_mask(sparams,
                                                    SND_PCM_HW_PARAM_FORMAT);
-       mask_none(tmp_mask);
+       mask_none(sfmt_mask);
+       mask_none(fmt_mask);
        for (format = 0; format <= SND_PCM_FORMAT_LAST; format++) {
                int f;
                if (!mask_test(format_mask, format))
@@ -275,80 +230,134 @@ static int snd_pcm_plug_hw_refine1(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
                        f = format;
                else {
                        f = snd_pcm_plug_slave_format(format, sformat_mask);
-                       if (f < 0) {
-                               mask_t *m = alloca(mask_sizeof());
-                               mask_all(m);
-                               mask_reset(m, format);
-                               err = _snd_pcm_hw_param_mask(params, 1, SND_PCM_HW_PARAM_FORMAT, m);
-                               if (err < 0)
-                                       return err;
+                       if (f < 0)
                                continue;
-                       }
                }
-               mask_set(tmp_mask, f);
+               mask_set(sfmt_mask, f);
+               mask_set(fmt_mask, format);
        }
 
-       err = _snd_pcm_hw_param_mask(sparams, 0, 
-                                     SND_PCM_HW_PARAM_FORMAT, tmp_mask);
+       err = _snd_pcm_hw_param_mask(params, 
+                                    SND_PCM_HW_PARAM_FORMAT, fmt_mask);
+       if (err < 0)
+               return err;
+       err = _snd_pcm_hw_param_mask(sparams,
+                                    SND_PCM_HW_PARAM_FORMAT, sfmt_mask);
        assert(err >= 0);
-       sformat_mask = snd_pcm_hw_param_value_mask(sparams,
-                                                   SND_PCM_HW_PARAM_FORMAT);
 
-       same_rate = (rate_min == rate_max && 
-                    rate_min == srate_min &&
-                    rate_min == srate_max);
-       if (same_rate)
+       format_always = snd_pcm_hw_param_always_eq(params,
+                                                  SND_PCM_HW_PARAM_FORMAT,
+                                                  sparams);
+       format_never = (!format_always &&
+                       snd_pcm_hw_param_never_eq(params,
+                                                 SND_PCM_HW_PARAM_FORMAT,
+                                                 sparams));
+               
+       channels_always = snd_pcm_hw_param_always_eq(params,
+                                                    SND_PCM_HW_PARAM_CHANNELS,
+                                                    sparams);
+       channels_never = (!channels_always &&
+                         snd_pcm_hw_param_never_eq(params,
+                                                   SND_PCM_HW_PARAM_CHANNELS,
+                                                   sparams));
+               
+       rate_always = snd_pcm_hw_param_always_eq(params,
+                                                SND_PCM_HW_PARAM_RATE,
+                                                sparams);
+       rate_never = (!rate_always &&
+                     snd_pcm_hw_param_never_eq(params,
+                                               SND_PCM_HW_PARAM_RATE,
+                                               sparams));
+       access_always = snd_pcm_hw_param_always_eq(params,
+                                                  SND_PCM_HW_PARAM_ACCESS,
+                                                  sparams);
+       access_never = (!access_always &&
+                       snd_pcm_hw_param_never_eq(params,
+                                                 SND_PCM_HW_PARAM_ACCESS,
+                                                 sparams));
+
+       if (rate_always)
                links |= (SND_PCM_HW_PARBIT_RATE |
-                         SND_PCM_HW_PARBIT_FRAGMENT_SIZE |
+                         SND_PCM_HW_PARBIT_PERIOD_SIZE |
+                         SND_PCM_HW_PARBIT_PERIODS |
+                         SND_PCM_HW_PARBIT_BUFFER_TIME |
                          SND_PCM_HW_PARBIT_BUFFER_SIZE);
-       same_channels = (channels_min == channels_max && 
-                        channels_min == schannels_min &&
-                        channels_min == schannels_max);
-       if (same_channels)
+       else {
+               interval_t t;
+               const interval_t *sbuffer_size, *buffer_size;
+               const interval_t *srate, *rate;
+               buffer_size = snd_pcm_hw_param_value_interval(params, SND_PCM_HW_PARAM_BUFFER_SIZE);
+               sbuffer_size = snd_pcm_hw_param_value_interval(sparams, SND_PCM_HW_PARAM_BUFFER_SIZE);
+               rate = snd_pcm_hw_param_value_interval(params, SND_PCM_HW_PARAM_RATE);
+               srate = snd_pcm_hw_param_value_interval(sparams, SND_PCM_HW_PARAM_RATE);
+               interval_muldiv(sbuffer_size, rate, srate, &t);
+               interval_round(&t);
+               err = _snd_pcm_hw_param_refine_interval(params, SND_PCM_HW_PARAM_BUFFER_SIZE, &t);
+               if (err < 0)
+                       return err;
+               interval_muldiv(buffer_size, srate, rate, &t);
+               interval_round(&t);
+               err = _snd_pcm_hw_param_refine_interval(sparams, SND_PCM_HW_PARAM_BUFFER_SIZE, &t);
+               assert(err >= 0);
+               scmask |= sparams->cmask;
+       }
+       if (channels_always)
                links |= SND_PCM_HW_PARBIT_CHANNELS;
-       same_format = (mask_single(format_mask) && 
-                      mask_eq(format_mask, sformat_mask));
-       if (same_format) {
+       if (format_always) {
                links |= (SND_PCM_HW_PARBIT_FORMAT |
                          SND_PCM_HW_PARBIT_SUBFORMAT |
                          SND_PCM_HW_PARBIT_SAMPLE_BITS);
-               if (same_channels) {
+               if (channels_always) {
                        links |= SND_PCM_HW_PARBIT_FRAME_BITS;
-                       if (same_rate
-                               links |= (SND_PCM_HW_PARBIT_FRAGMENT_BYTES |
+                       if (rate_always
+                               links |= (SND_PCM_HW_PARBIT_PERIOD_BYTES |
                                          SND_PCM_HW_PARBIT_BUFFER_BYTES);
                }
        }
 
-       if (same_rate && same_channels && same_format) {
-               const mask_t *access_mask = snd_pcm_hw_param_value_mask(params, SND_PCM_HW_PARAM_ACCESS);
-               mask_copy(tmp_mask, snd_pcm_hw_param_value_mask(sparams, SND_PCM_HW_PARAM_ACCESS));
-               mask_intersect(tmp_mask, access_mask);
-               if (!mask_empty(tmp_mask))
-                       _snd_pcm_hw_param_mask(sparams, 0,
-                                               SND_PCM_HW_PARAM_ACCESS,
-                                               access_mask);
-               else
-                 _snd_pcm_hw_param_mask(sparams, 0, SND_PCM_HW_PARAM_ACCESS,
-                                         mmap_mask);
-       } else {
-               err = _snd_pcm_hw_param_mask(params, 1,
-                                             SND_PCM_HW_PARAM_ACCESS,
-                                             accplug_mask);
-               if (err < 0)
-                       return err;
-               err = _snd_pcm_hw_param_mask(params, 1,
-                                             SND_PCM_HW_PARAM_FORMAT,
-                                             fmtplug_mask);
-               if (err < 0)
-                       return err;
-               _snd_pcm_hw_param_mask(sparams, 0, SND_PCM_HW_PARAM_ACCESS,
-                                       mmap_mask);
-               _snd_pcm_hw_param_mask(sparams, 0, SND_PCM_HW_PARAM_FORMAT,
-                                       fmtplug_mask);
-       }
+       mask_load(access_mask, SND_PCM_ACCBIT_PLUGIN);
+       if (format_never || channels_never || rate_never) {
+               mask_t *mmap_mask = alloca(mask_sizeof());
+               mask_load(mmap_mask, SND_PCM_ACCBIT_MMAP);
+               _snd_pcm_hw_param_mask(sparams, SND_PCM_HW_PARAM_ACCESS,
+                                      mmap_mask);
+       } else
+               mask_union(access_mask, snd_pcm_hw_param_value_mask(sparams, SND_PCM_HW_PARAM_ACCESS));
+       _snd_pcm_hw_param_mask(params, SND_PCM_HW_PARAM_ACCESS,
+                              access_mask);
+       sparams->cmask |= scmask;
+       return snd_pcm_generic_hw_link(params, sparams, slave, links);
+}
+
+static int snd_pcm_plug_hw_refine1(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
+                                  snd_pcm_hw_params_t *sparams)
+{
+       snd_pcm_plug_t *plug = pcm->private;
+       snd_pcm_t *slave = plug->req_slave;
+       unsigned int cmask, lcmask;
+       int err;
+       
+       cmask = params->cmask;
+       params->cmask = 0;
+       err = _snd_pcm_hw_param_min(params, SND_PCM_HW_PARAM_CHANNELS, 1, 0);
+       if (err < 0)
+               return err;
+       err = _snd_pcm_hw_param_max(params, SND_PCM_HW_PARAM_CHANNELS, 1024, 0);
+       if (err < 0)
+               return err;
+       err = _snd_pcm_hw_param_min(params, SND_PCM_HW_PARAM_RATE, RATE_MIN, 0);
+       if (err < 0)
+               return err;
+       err = _snd_pcm_hw_param_max(params, SND_PCM_HW_PARAM_RATE, RATE_MAX, 0);
+       if (err < 0)
+               return err;
+       lcmask = params->cmask;
+       params->cmask |= cmask;
+
+       _snd_pcm_hw_params_any(sparams);
        err = snd_pcm_hw_refine2(params, sparams,
-                                snd_pcm_hw_refine, slave, links);
+                                snd_pcm_plug_hw_link, slave, 0);
+       params->cmask |= lcmask;
        if (err < 0)
                return err;
        params->info &= ~(SND_PCM_INFO_MMAP | SND_PCM_INFO_MMAP_VALID);
@@ -360,7 +369,19 @@ static int snd_pcm_plug_hw_refine1(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
 static int snd_pcm_plug_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
 {
        snd_pcm_hw_params_t sparams;
-       return snd_pcm_plug_hw_refine1(pcm, params, &sparams);
+       int err;
+#if 0
+       fprintf(stderr, "Enter: client =\n");
+       snd_pcm_hw_params_dump(params, stderr);
+#endif
+       err = snd_pcm_plug_hw_refine1(pcm, params, &sparams);
+#if 0
+       fprintf(stderr, "Exit: client =\n");
+       snd_pcm_hw_params_dump(params, stderr);
+       fprintf(stderr, "Exit: slave =\n");
+       snd_pcm_hw_params_dump(&sparams, stderr);
+#endif
+       return err;
 }
 
 static void snd_pcm_plug_clear(snd_pcm_t *pcm)
@@ -584,15 +605,15 @@ static int snd_pcm_plug_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
        int err = snd_pcm_plug_hw_refine1(pcm, params, &sparams);
        assert(err >= 0);
 
-       clt_params.access = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_ACCESS);
-       clt_params.format = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FORMAT);
-       clt_params.channels = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_CHANNELS);
-       clt_params.rate = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_RATE);
+       clt_params.access = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_ACCESS, 0);
+       clt_params.format = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FORMAT, 0);
+       clt_params.channels = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_CHANNELS, 0);
+       clt_params.rate = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_RATE, 0);
 
-       slv_params.access = snd_pcm_hw_param_first(slave, &sparams, SND_PCM_HW_PARAM_ACCESS);
-       slv_params.format = snd_pcm_hw_param_value(&sparams, SND_PCM_HW_PARAM_FORMAT);
-       slv_params.channels = snd_pcm_hw_param_value(&sparams, SND_PCM_HW_PARAM_CHANNELS);
-       slv_params.rate = snd_pcm_hw_param_value(&sparams, SND_PCM_HW_PARAM_RATE);
+       slv_params.access = snd_pcm_hw_param_first(slave, &sparams, SND_PCM_HW_PARAM_ACCESS, 0);
+       slv_params.format = snd_pcm_hw_param_value(&sparams, SND_PCM_HW_PARAM_FORMAT, 0);
+       slv_params.channels = snd_pcm_hw_param_value(&sparams, SND_PCM_HW_PARAM_CHANNELS, 0);
+       slv_params.rate = snd_pcm_hw_param_value(&sparams, SND_PCM_HW_PARAM_RATE, 0);
 
        snd_pcm_plug_clear(pcm);
        err = snd_pcm_plug_insert_plugins(pcm, &clt_params, &slv_params);
@@ -612,7 +633,7 @@ static int snd_pcm_plug_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t * params)
 {
        snd_pcm_plug_t *plug = pcm->private;
        snd_pcm_t *slave = plug->req_slave;
-       size_t avail_min, xfer_align, silence_threshold, silence_size;
+       snd_pcm_uframes_t avail_min, xfer_align, silence_threshold, silence_size;
        int err;
        avail_min = params->avail_min;
        xfer_align = params->xfer_align;
index 8fa3ccadf3d9c22a6ad3f467002d39bdaa33ba8e..f98d08f7dc8f2981930e28bdab23691896626c83 100644 (file)
@@ -88,10 +88,10 @@ int snd_pcm_plugin_state(snd_pcm_t *pcm)
        return snd_pcm_state(plugin->slave);
 }
 
-int snd_pcm_plugin_delay(snd_pcm_t *pcm, ssize_t *delayp)
+int snd_pcm_plugin_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp)
 {
        snd_pcm_plugin_t *plugin = pcm->private;
-       ssize_t sd;
+       snd_pcm_sframes_t sd;
        int err = snd_pcm_delay(plugin->slave, &sd);
        if (err < 0)
                return err;
@@ -157,18 +157,18 @@ int snd_pcm_plugin_pause(snd_pcm_t *pcm, int enable)
        return snd_pcm_pause(plugin->slave, enable);
 }
 
-ssize_t snd_pcm_plugin_rewind(snd_pcm_t *pcm, size_t frames)
+snd_pcm_sframes_t snd_pcm_plugin_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
 {
        snd_pcm_plugin_t *plugin = pcm->private;
-       ssize_t n = snd_pcm_mmap_hw_avail(pcm);
+       snd_pcm_sframes_t n = snd_pcm_mmap_hw_avail(pcm);
        assert(n >= 0);
        if (n > 0) {
-               if ((size_t)n > frames)
+               if ((snd_pcm_uframes_t)n > frames)
                        n = frames;
                frames -= n;
        }
        if (frames > 0) {
-               ssize_t err;
+               snd_pcm_sframes_t err;
                /* FIXME: rate plugin */
                if (plugin->slave_frames)
                        frames = plugin->slave_frames(pcm, frames);
@@ -188,11 +188,11 @@ ssize_t snd_pcm_plugin_rewind(snd_pcm_t *pcm, size_t frames)
        return n;
 }
 
-ssize_t snd_pcm_plugin_writei(snd_pcm_t *pcm, const void *buffer, size_t size)
+snd_pcm_sframes_t snd_pcm_plugin_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size)
 {
        snd_pcm_plugin_t *plugin = pcm->private;
        snd_pcm_channel_area_t areas[pcm->channels];
-       ssize_t frames;
+       snd_pcm_sframes_t frames;
        snd_pcm_areas_from_buf(pcm, areas, (void*)buffer);
        frames = snd_pcm_write_areas(pcm, areas, 0, size, plugin->write);
        if (frames > 0)
@@ -200,11 +200,11 @@ ssize_t snd_pcm_plugin_writei(snd_pcm_t *pcm, const void *buffer, size_t size)
        return frames;
 }
 
-ssize_t snd_pcm_plugin_writen(snd_pcm_t *pcm, void **bufs, size_t size)
+snd_pcm_sframes_t snd_pcm_plugin_writen(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size)
 {
        snd_pcm_plugin_t *plugin = pcm->private;
        snd_pcm_channel_area_t areas[pcm->channels];
-       ssize_t frames;
+       snd_pcm_sframes_t frames;
        snd_pcm_areas_from_bufs(pcm, areas, bufs);
        frames = snd_pcm_write_areas(pcm, areas, 0, size, plugin->write);
        if (frames > 0)
@@ -212,11 +212,11 @@ ssize_t snd_pcm_plugin_writen(snd_pcm_t *pcm, void **bufs, size_t size)
        return frames;
 }
 
-ssize_t snd_pcm_plugin_readi(snd_pcm_t *pcm, void *buffer, size_t size)
+snd_pcm_sframes_t snd_pcm_plugin_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size)
 {
        snd_pcm_plugin_t *plugin = pcm->private;
        snd_pcm_channel_area_t areas[pcm->channels];
-       ssize_t frames;
+       snd_pcm_sframes_t frames;
        snd_pcm_areas_from_buf(pcm, areas, buffer);
        frames = snd_pcm_read_areas(pcm, areas, 0, size, plugin->read);
        if (frames > 0)
@@ -224,11 +224,11 @@ ssize_t snd_pcm_plugin_readi(snd_pcm_t *pcm, void *buffer, size_t size)
        return frames;
 }
 
-ssize_t snd_pcm_plugin_readn(snd_pcm_t *pcm, void **bufs, size_t size)
+snd_pcm_sframes_t snd_pcm_plugin_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size)
 {
        snd_pcm_plugin_t *plugin = pcm->private;
        snd_pcm_channel_area_t areas[pcm->channels];
-       ssize_t frames;
+       snd_pcm_sframes_t frames;
        snd_pcm_areas_from_bufs(pcm, areas, bufs);
        frames = snd_pcm_read_areas(pcm, areas, 0, size, plugin->read);
        if (frames > 0)
@@ -236,14 +236,14 @@ ssize_t snd_pcm_plugin_readn(snd_pcm_t *pcm, void **bufs, size_t size)
        return frames;
 }
 
-ssize_t snd_pcm_plugin_mmap_forward(snd_pcm_t *pcm, size_t client_size)
+snd_pcm_sframes_t snd_pcm_plugin_mmap_forward(snd_pcm_t *pcm, snd_pcm_uframes_t client_size)
 {
        snd_pcm_plugin_t *plugin = pcm->private;
        snd_pcm_t *slave = plugin->slave;
-       size_t client_xfer = 0;
-       size_t slave_xfer = 0;
-       ssize_t err = 0;
-       ssize_t slave_size;
+       snd_pcm_uframes_t client_xfer = 0;
+       snd_pcm_uframes_t slave_xfer = 0;
+       snd_pcm_sframes_t err = 0;
+       snd_pcm_sframes_t slave_size;
        if (pcm->stream == SND_PCM_STREAM_CAPTURE) {
                snd_pcm_mmap_appl_forward(pcm, client_size);
                // snd_pcm_plugin_avail_update(pcm);
@@ -253,11 +253,11 @@ ssize_t snd_pcm_plugin_mmap_forward(snd_pcm_t *pcm, size_t client_size)
        if (slave_size <= 0)
                return slave_size;
        while (client_xfer < client_size &&
-              slave_xfer < (size_t)slave_size) {
-               size_t slave_frames = slave_size - slave_xfer;
-               size_t client_frames = client_size - client_xfer;
-               size_t offset = snd_pcm_mmap_hw_offset(pcm);
-               size_t cont = pcm->buffer_size - offset;
+              slave_xfer < (snd_pcm_uframes_t)slave_size) {
+               snd_pcm_uframes_t slave_frames = slave_size - slave_xfer;
+               snd_pcm_uframes_t client_frames = client_size - client_xfer;
+               snd_pcm_uframes_t offset = snd_pcm_mmap_hw_offset(pcm);
+               snd_pcm_uframes_t cont = pcm->buffer_size - offset;
                if (cont < client_frames)
                        client_frames = cont;
                err = plugin->write(pcm, pcm->running_areas, offset,
@@ -273,15 +273,15 @@ ssize_t snd_pcm_plugin_mmap_forward(snd_pcm_t *pcm, size_t client_size)
        return err;
 }
 
-ssize_t snd_pcm_plugin_avail_update(snd_pcm_t *pcm)
+snd_pcm_sframes_t snd_pcm_plugin_avail_update(snd_pcm_t *pcm)
 {
        snd_pcm_plugin_t *plugin = pcm->private;
        snd_pcm_t *slave = plugin->slave;
-       size_t client_xfer;
-       size_t slave_xfer = 0;
-       ssize_t err = 0;
-       size_t client_size;
-       ssize_t slave_size = snd_pcm_avail_update(slave);
+       snd_pcm_uframes_t client_xfer;
+       snd_pcm_uframes_t slave_xfer = 0;
+       snd_pcm_sframes_t err = 0;
+       snd_pcm_uframes_t client_size;
+       snd_pcm_sframes_t slave_size = snd_pcm_avail_update(slave);
        if (slave_size <= 0)
                return slave_size;
        if (pcm->stream == SND_PCM_STREAM_PLAYBACK ||
@@ -291,12 +291,12 @@ ssize_t snd_pcm_plugin_avail_update(snd_pcm_t *pcm)
                        plugin->client_frames(pcm, slave_size) : slave_size;
        client_xfer = snd_pcm_mmap_capture_avail(pcm);
        client_size = pcm->buffer_size;
-       while (slave_xfer < (size_t)slave_size &&
+       while (slave_xfer < (snd_pcm_uframes_t)slave_size &&
               client_xfer < client_size) {
-               size_t slave_frames = slave_size - slave_xfer;
-               size_t client_frames = client_size - client_xfer;
-               size_t offset = snd_pcm_mmap_hw_offset(pcm);
-               size_t cont = pcm->buffer_size - offset;
+               snd_pcm_uframes_t slave_frames = slave_size - slave_xfer;
+               snd_pcm_uframes_t client_frames = client_size - client_xfer;
+               snd_pcm_uframes_t offset = snd_pcm_mmap_hw_offset(pcm);
+               snd_pcm_uframes_t cont = pcm->buffer_size - offset;
                if (cont < client_frames)
                        client_frames = cont;
                err = plugin->read(pcm, pcm->running_areas, offset,
index 06d14cc0e91faf3f3fb4f015ebd96e8205be478e..ef723353bb03ced89ccd400db73bb228b2a0b395 100644 (file)
@@ -24,11 +24,11 @@ typedef struct {
        int close_slave;
        snd_pcm_xfer_areas_func_t read;
        snd_pcm_xfer_areas_func_t write;
-       ssize_t (*client_frames)(snd_pcm_t *pcm, ssize_t frames);
-       ssize_t (*slave_frames)(snd_pcm_t *pcm, ssize_t frames);
+       snd_pcm_sframes_t (*client_frames)(snd_pcm_t *pcm, snd_pcm_sframes_t frames);
+       snd_pcm_sframes_t (*slave_frames)(snd_pcm_t *pcm, snd_pcm_sframes_t frames);
        int (*init)(snd_pcm_t *pcm);
        int shmid;
-       size_t appl_ptr, hw_ptr;
+       snd_pcm_uframes_t appl_ptr, hw_ptr;
 } snd_pcm_plugin_t;    
 
 int snd_pcm_plugin_close(snd_pcm_t *pcm);
@@ -41,19 +41,19 @@ int snd_pcm_plugin_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t *params);
 int snd_pcm_plugin_channel_info(snd_pcm_t *pcm, snd_pcm_channel_info_t * info);
 int snd_pcm_plugin_status(snd_pcm_t *pcm, snd_pcm_status_t * status);
 int snd_pcm_plugin_state(snd_pcm_t *pcm);
-int snd_pcm_plugin_delay(snd_pcm_t *pcm, ssize_t *delayp);
+int snd_pcm_plugin_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp);
 int snd_pcm_plugin_prepare(snd_pcm_t *pcm);
 int snd_pcm_plugin_start(snd_pcm_t *pcm);
 int snd_pcm_plugin_drop(snd_pcm_t *pcm);
 int snd_pcm_plugin_drain(snd_pcm_t *pcm);
 int snd_pcm_plugin_pause(snd_pcm_t *pcm, int enable);
-ssize_t snd_pcm_plugin_rewind(snd_pcm_t *pcm, size_t frames);
-ssize_t snd_pcm_plugin_writei(snd_pcm_t *pcm, const void *buffer, size_t size);
-ssize_t snd_pcm_plugin_writen(snd_pcm_t *pcm, void **bufs, size_t size);
-ssize_t snd_pcm_plugin_readi(snd_pcm_t *pcm, void *buffer, size_t size);
-ssize_t snd_pcm_plugin_readn(snd_pcm_t *pcm, void **bufs, size_t size);
-ssize_t snd_pcm_plugin_mmap_forward(snd_pcm_t *pcm, size_t size);
-ssize_t snd_pcm_plugin_avail_update(snd_pcm_t *pcm);
+snd_pcm_sframes_t snd_pcm_plugin_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
+snd_pcm_sframes_t snd_pcm_plugin_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size);
+snd_pcm_sframes_t snd_pcm_plugin_writen(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size);
+snd_pcm_sframes_t snd_pcm_plugin_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size);
+snd_pcm_sframes_t snd_pcm_plugin_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size);
+snd_pcm_sframes_t snd_pcm_plugin_mmap_forward(snd_pcm_t *pcm, snd_pcm_uframes_t size);
+snd_pcm_sframes_t snd_pcm_plugin_avail_update(snd_pcm_t *pcm);
 int snd_pcm_plugin_mmap_status(snd_pcm_t *pcm);
 int snd_pcm_plugin_mmap_control(snd_pcm_t *pcm);
 int snd_pcm_plugin_mmap(snd_pcm_t *pcm);
index 9f616ea1c5e0b284c96823f1ba6d625c49bf81e5..351d853fc86b195b0ddd9b45b87f28bfd9f07ba7 100644 (file)
@@ -32,11 +32,11 @@ typedef struct {
        unsigned int pos;
 } rate_state_t;
  
-typedef size_t (*rate_f)(const snd_pcm_channel_area_t *src_areas,
-                        size_t src_offset, size_t src_frames,
+typedef snd_pcm_uframes_t (*rate_f)(const snd_pcm_channel_area_t *src_areas,
+                        snd_pcm_uframes_t src_offset, snd_pcm_uframes_t src_frames,
                         const snd_pcm_channel_area_t *dst_areas,
-                        size_t dst_offset, size_t *dst_framesp,
-                        size_t channels,
+                        snd_pcm_uframes_t dst_offset, snd_pcm_uframes_t *dst_framesp,
+                        unsigned int channels,
                         int getidx, int putidx,
                         unsigned int arg,
                         rate_state_t *states);
@@ -53,11 +53,11 @@ typedef struct {
        rate_state_t *states;
 } snd_pcm_rate_t;
 
-static size_t resample_expand(const snd_pcm_channel_area_t *src_areas,
-                             size_t src_offset, size_t src_frames,
+static snd_pcm_uframes_t resample_expand(const snd_pcm_channel_area_t *src_areas,
+                             snd_pcm_uframes_t src_offset, snd_pcm_uframes_t src_frames,
                              const snd_pcm_channel_area_t *dst_areas,
-                             size_t dst_offset, size_t *dst_framesp,
-                             size_t channels,
+                             snd_pcm_uframes_t dst_offset, snd_pcm_uframes_t *dst_framesp,
+                             unsigned int channels,
                              int getidx, int putidx,
                              unsigned int get_threshold,
                              rate_state_t *states)
@@ -70,9 +70,9 @@ static size_t resample_expand(const snd_pcm_channel_area_t *src_areas,
        void *get = get16_labels[getidx];
        void *put = put16_labels[putidx];
        unsigned int channel;
-       size_t src_frames1 = 0;
-       size_t dst_frames1 = 0;
-       size_t dst_frames = *dst_framesp;
+       snd_pcm_uframes_t src_frames1 = 0;
+       snd_pcm_uframes_t dst_frames1 = 0;
+       snd_pcm_uframes_t dst_frames = *dst_framesp;
        int16_t sample = 0;
        
        if (src_frames == 0 ||
@@ -135,11 +135,11 @@ static size_t resample_expand(const snd_pcm_channel_area_t *src_areas,
        return src_frames1;
 }
 
-static size_t resample_shrink(const snd_pcm_channel_area_t *src_areas,
-                             size_t src_offset, size_t src_frames,
+static snd_pcm_uframes_t resample_shrink(const snd_pcm_channel_area_t *src_areas,
+                             snd_pcm_uframes_t src_offset, snd_pcm_uframes_t src_frames,
                              const snd_pcm_channel_area_t *dst_areas,
-                             size_t dst_offset, size_t *dst_framesp,
-                             size_t channels,
+                             snd_pcm_uframes_t dst_offset, snd_pcm_uframes_t *dst_framesp,
+                             unsigned int channels,
                              int getidx, int putidx,
                              unsigned int get_increment,
                              rate_state_t *states)
@@ -152,9 +152,9 @@ static size_t resample_shrink(const snd_pcm_channel_area_t *src_areas,
        void *get = get16_labels[getidx];
        void *put = put16_labels[putidx];
        unsigned int channel;
-       size_t src_frames1 = 0;
-       size_t dst_frames1 = 0;
-       size_t dst_frames = *dst_framesp;
+       snd_pcm_uframes_t src_frames1 = 0;
+       snd_pcm_uframes_t dst_frames1 = 0;
+       snd_pcm_uframes_t dst_frames = *dst_framesp;
        int16_t sample = 0;
 
        if (src_frames == 0 ||
@@ -238,52 +238,60 @@ static int snd_pcm_rate_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
        snd_pcm_rate_t *rate = pcm->private;
        snd_pcm_t *slave = rate->plug.slave;
        int err;
+       unsigned int cmask, lcmask;
        snd_pcm_hw_params_t sparams;
        unsigned int links = (SND_PCM_HW_PARBIT_CHANNELS |
-                             SND_PCM_HW_PARBIT_FRAGMENTS |
-                             SND_PCM_HW_PARBIT_FRAGMENT_LENGTH |
-                             SND_PCM_HW_PARBIT_BUFFER_LENGTH);
+                             SND_PCM_HW_PARBIT_PERIOD_TIME |
+                             SND_PCM_HW_PARBIT_TICK_TIME);
        mask_t *access_mask = alloca(mask_sizeof());
        mask_t *format_mask = alloca(mask_sizeof());
        mask_t *saccess_mask = alloca(mask_sizeof());
        mask_load(access_mask, SND_PCM_ACCBIT_PLUGIN);
        mask_load(format_mask, SND_PCM_FMTBIT_LINEAR);
        mask_load(saccess_mask, SND_PCM_ACCBIT_MMAP);
-       err = _snd_pcm_hw_param_mask(params, 1, SND_PCM_HW_PARAM_ACCESS,
+       cmask = params->cmask;
+       params->cmask = 0;
+       err = _snd_pcm_hw_param_mask(params, SND_PCM_HW_PARAM_ACCESS,
                                      access_mask);
        if (err < 0)
                return err;
-       err = _snd_pcm_hw_param_mask(params, 1, SND_PCM_HW_PARAM_FORMAT,
+       err = _snd_pcm_hw_param_mask(params, SND_PCM_HW_PARAM_FORMAT,
                                      format_mask);
        if (err < 0)
                return err;
-       err = _snd_pcm_hw_param_min(params, 1,
-                                    SND_PCM_HW_PARAM_RATE, RATE_MIN);
+       err = _snd_pcm_hw_param_min(params,
+                                    SND_PCM_HW_PARAM_RATE, RATE_MIN, 0);
        if (err < 0)
                return err;
-       err = _snd_pcm_hw_param_max(params, 1,
-                                    SND_PCM_HW_PARAM_RATE, RATE_MAX);
+       err = _snd_pcm_hw_param_max(params,
+                                    SND_PCM_HW_PARAM_RATE, RATE_MAX, 0);
        if (err < 0)
                return err;
+       lcmask = params->cmask;
+       params->cmask |= cmask;
 
        _snd_pcm_hw_params_any(&sparams);
-       _snd_pcm_hw_param_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
+       _snd_pcm_hw_param_mask(&sparams, SND_PCM_HW_PARAM_ACCESS,
                                saccess_mask);
+       snd_pcm_hw_param_near_copy(slave, &sparams,
+                                  SND_PCM_HW_PARAM_BUFFER_TIME,
+                                  params);
        if (rate->sformat >= 0) {
-               _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_FORMAT,
-                                      rate->sformat);
-               _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_SUBFORMAT,
-                                      SND_PCM_SUBFORMAT_STD);
+               _snd_pcm_hw_param_set(&sparams, SND_PCM_HW_PARAM_FORMAT,
+                                     rate->sformat, 0);
+               _snd_pcm_hw_param_set(&sparams, SND_PCM_HW_PARAM_SUBFORMAT,
+                                     SND_PCM_SUBFORMAT_STD, 0);
        } else
                links |= (SND_PCM_HW_PARBIT_FORMAT |
                          SND_PCM_HW_PARBIT_SUBFORMAT |
                          SND_PCM_HW_PARBIT_SAMPLE_BITS |
                          SND_PCM_HW_PARBIT_FRAME_BITS);
-       _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_RATE,
-                              rate->srate);
+       _snd_pcm_hw_param_set(&sparams, SND_PCM_HW_PARAM_RATE,
+                             rate->srate, 0);
                
        err = snd_pcm_hw_refine2(params, &sparams,
-                                snd_pcm_hw_refine, slave, links);
+                                snd_pcm_generic_hw_link, slave, links);
+       params->cmask |= lcmask;
        if (err < 0)
                return err;
        params->info &= ~(SND_PCM_INFO_MMAP | SND_PCM_INFO_MMAP_VALID);
@@ -297,45 +305,55 @@ static int snd_pcm_rate_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
        int err;
        snd_pcm_hw_params_t sparams;
        unsigned int links = (SND_PCM_HW_PARBIT_CHANNELS |
-                             SND_PCM_HW_PARBIT_FRAGMENTS |
-                             SND_PCM_HW_PARBIT_FRAGMENT_LENGTH |
-                             SND_PCM_HW_PARBIT_BUFFER_LENGTH);
+                             SND_PCM_HW_PARBIT_PERIOD_TIME |
+                             SND_PCM_HW_PARBIT_TICK_TIME);
        unsigned int src_format, dst_format;
        unsigned int src_rate, dst_rate;
        mask_t *saccess_mask = alloca(mask_sizeof());
        mask_load(saccess_mask, SND_PCM_ACCBIT_MMAP);
 
        _snd_pcm_hw_params_any(&sparams);
-       _snd_pcm_hw_param_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
+       _snd_pcm_hw_param_mask(&sparams, SND_PCM_HW_PARAM_ACCESS,
                                saccess_mask);
        if (rate->sformat >= 0) {
-               _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_FORMAT,
-                                      rate->sformat);
-               _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_SUBFORMAT,
-                                      SND_PCM_SUBFORMAT_STD);
+               _snd_pcm_hw_param_set(&sparams, SND_PCM_HW_PARAM_FORMAT,
+                                     rate->sformat, 0);
+               _snd_pcm_hw_param_set(&sparams, SND_PCM_HW_PARAM_SUBFORMAT,
+                                     SND_PCM_SUBFORMAT_STD, 0);
        } else
                links |= (SND_PCM_HW_PARBIT_FORMAT |
                          SND_PCM_HW_PARBIT_SUBFORMAT |
                          SND_PCM_HW_PARBIT_SAMPLE_BITS |
                          SND_PCM_HW_PARBIT_FRAME_BITS);
-       _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_RATE,
-                              rate->srate);
+
+       _snd_pcm_hw_param_set(&sparams, SND_PCM_HW_PARAM_RATE,
+                             rate->srate, 0);
+
+       snd_pcm_hw_param_near_copy(slave, &sparams,
+                                  SND_PCM_HW_PARAM_BUFFER_TIME,
+                                  params);
                
-       err = snd_pcm_hw_params2(params, &sparams,
-                                snd_pcm_hw_params, slave, links);
+       err = snd_pcm_hw_params_refine(&sparams, links, params);
+       assert(err >= 0);
+       err = _snd_pcm_hw_refine(&sparams);
+       assert(err >= 0);
+       err = snd_pcm_hw_params(slave, &sparams);
+       params->cmask = 0;
+       sparams.cmask = ~0U;
+       snd_pcm_hw_params_refine(params, links, &sparams);
        if (err < 0)
                return err;
        params->info &= ~(SND_PCM_INFO_MMAP | SND_PCM_INFO_MMAP_VALID);
        if (pcm->stream == SND_PCM_STREAM_PLAYBACK) {
-               src_format = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FORMAT);
+               src_format = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FORMAT, 0);
                dst_format = slave->format;
-               src_rate = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_RATE);
+               src_rate = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_RATE, 0);
                dst_rate = slave->rate;
        } else {
                src_format = slave->format;
-               dst_format = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FORMAT);
+               dst_format = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FORMAT, 0);
                src_rate = slave->rate;
-               dst_rate = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_RATE);
+               dst_rate = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_RATE, 0);
        }
        rate->get_idx = get_index(src_format, SND_PCM_FORMAT_S16);
        rate->put_idx = put_index(SND_PCM_FORMAT_S16, dst_format);
@@ -349,7 +367,7 @@ static int snd_pcm_rate_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
        rate->pitch = (((u_int64_t)dst_rate * DIV) + src_rate / 2) / src_rate;
        if (rate->states)
                free(rate->states);
-       rate->states = malloc(snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_CHANNELS) * sizeof(*rate->states));
+       rate->states = malloc(snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_CHANNELS, 0) * sizeof(*rate->states));
        return 0;
 }
 
@@ -357,7 +375,7 @@ static int snd_pcm_rate_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t * params)
 {
        snd_pcm_rate_t *rate = pcm->private;
        snd_pcm_t *slave = rate->plug.slave;
-       size_t avail_min, xfer_align, silence_threshold, silence_size;
+       snd_pcm_uframes_t avail_min, xfer_align, silence_threshold, silence_size;
        int err;
        avail_min = params->avail_min;
        xfer_align = params->xfer_align;
@@ -393,18 +411,18 @@ static int snd_pcm_rate_init(snd_pcm_t *pcm)
        return 0;
 }
 
-static ssize_t snd_pcm_rate_write_areas(snd_pcm_t *pcm,
+static snd_pcm_sframes_t snd_pcm_rate_write_areas(snd_pcm_t *pcm,
                                        const snd_pcm_channel_area_t *areas,
-                                       size_t client_offset,
-                                       size_t client_size,
-                                       size_t *slave_sizep)
+                                       snd_pcm_uframes_t client_offset,
+                                       snd_pcm_uframes_t client_size,
+                                       snd_pcm_uframes_t *slave_sizep)
 {
        snd_pcm_rate_t *rate = pcm->private;
        snd_pcm_t *slave = rate->plug.slave;
-       size_t client_xfer = 0;
-       size_t slave_xfer = 0;
-       ssize_t err = 0;
-       size_t slave_size;
+       snd_pcm_uframes_t client_xfer = 0;
+       snd_pcm_uframes_t slave_xfer = 0;
+       snd_pcm_sframes_t err = 0;
+       snd_pcm_uframes_t slave_size;
        if (slave_sizep)
                slave_size = *slave_sizep;
        else
@@ -412,7 +430,7 @@ static ssize_t snd_pcm_rate_write_areas(snd_pcm_t *pcm,
        assert(client_size > 0 && slave_size > 0);
        while (client_xfer < client_size &&
               slave_xfer < slave_size) {
-               size_t src_frames, dst_frames;
+               snd_pcm_uframes_t src_frames, dst_frames;
                src_frames = client_size - client_xfer;
                dst_frames = snd_pcm_mmap_playback_xfer(slave, slave_size - slave_xfer);
                src_frames = rate->func(areas, client_offset, src_frames,
@@ -426,7 +444,7 @@ static ssize_t snd_pcm_rate_write_areas(snd_pcm_t *pcm,
                        err = snd_pcm_mmap_forward(slave, dst_frames);
                        if (err < 0)
                                break;
-                       assert((size_t)err == dst_frames);
+                       assert((snd_pcm_uframes_t)err == dst_frames);
                        slave_xfer += dst_frames;
                }
 
@@ -444,19 +462,19 @@ static ssize_t snd_pcm_rate_write_areas(snd_pcm_t *pcm,
        return err;
 }
 
-static ssize_t snd_pcm_rate_read_areas(snd_pcm_t *pcm,
+static snd_pcm_sframes_t snd_pcm_rate_read_areas(snd_pcm_t *pcm,
                                       const snd_pcm_channel_area_t *areas,
-                                      size_t client_offset,
-                                      size_t client_size,
-                                      size_t *slave_sizep)
+                                      snd_pcm_uframes_t client_offset,
+                                      snd_pcm_uframes_t client_size,
+                                      snd_pcm_uframes_t *slave_sizep)
 
 {
        snd_pcm_rate_t *rate = pcm->private;
        snd_pcm_t *slave = rate->plug.slave;
-       size_t client_xfer = 0;
-       size_t slave_xfer = 0;
-       ssize_t err = 0;
-       size_t slave_size;
+       snd_pcm_uframes_t client_xfer = 0;
+       snd_pcm_uframes_t slave_xfer = 0;
+       snd_pcm_sframes_t err = 0;
+       snd_pcm_uframes_t slave_size;
        if (slave_sizep)
                slave_size = *slave_sizep;
        else
@@ -464,7 +482,7 @@ static ssize_t snd_pcm_rate_read_areas(snd_pcm_t *pcm,
        assert(client_size > 0 && slave_size > 0);
        while (client_xfer < client_size &&
               slave_xfer < slave_size) {
-               size_t src_frames, dst_frames;
+               snd_pcm_uframes_t src_frames, dst_frames;
                dst_frames = client_size - client_xfer;
                src_frames = snd_pcm_mmap_capture_xfer(slave, slave_size - slave_xfer);
                src_frames = rate->func(snd_pcm_mmap_areas(slave), snd_pcm_mmap_offset(slave),
@@ -478,7 +496,7 @@ static ssize_t snd_pcm_rate_read_areas(snd_pcm_t *pcm,
                        err = snd_pcm_mmap_forward(slave, src_frames);
                        if (err < 0)
                                break;
-                       assert((size_t)err == src_frames);
+                       assert((snd_pcm_uframes_t)err == src_frames);
                        slave_xfer += src_frames;
                }
                if (dst_frames > 0) {
@@ -495,7 +513,7 @@ static ssize_t snd_pcm_rate_read_areas(snd_pcm_t *pcm,
        return err;
 }
 
-ssize_t snd_pcm_rate_client_frames(snd_pcm_t *pcm, ssize_t frames)
+snd_pcm_sframes_t snd_pcm_rate_client_frames(snd_pcm_t *pcm, snd_pcm_sframes_t frames)
 {
        snd_pcm_rate_t *rate = pcm->private;
        /* Round toward zero */
@@ -505,7 +523,7 @@ ssize_t snd_pcm_rate_client_frames(snd_pcm_t *pcm, ssize_t frames)
                return muldiv_down(frames, rate->pitch, DIV);
 }
 
-ssize_t snd_pcm_rate_slave_frames(snd_pcm_t *pcm, ssize_t frames)
+snd_pcm_sframes_t snd_pcm_rate_slave_frames(snd_pcm_t *pcm, snd_pcm_sframes_t frames)
 {
        snd_pcm_rate_t *rate = pcm->private;
        /* Round toward zero */
index 15b7eb3059edc3741c8cd0853e3b6b8da3ca5934..c9125cb4475913c9f7ed9f70119e01c3038d24ec 100644 (file)
@@ -50,16 +50,16 @@ typedef struct {
        int conv_idx;
        int src_size;
        int dst_sfmt;
-       size_t ndsts;
+       unsigned int ndsts;
        ttable_dst_t *dsts;
 } route_params_t;
 
 
 typedef void (*route_f)(const snd_pcm_channel_area_t *src_areas,
-                       size_t src_offset,
+                       snd_pcm_uframes_t src_offset,
                        const snd_pcm_channel_area_t *dst_area,
-                       size_t dst_offset,
-                       size_t frames,
+                       snd_pcm_uframes_t dst_offset,
+                       snd_pcm_uframes_t frames,
                        const ttable_dst_t *ttable,
                        const route_params_t *params);
 
@@ -88,10 +88,10 @@ typedef struct {
 
 
 static void route1_zero(const snd_pcm_channel_area_t *src_areas ATTRIBUTE_UNUSED,
-                       size_t src_offset ATTRIBUTE_UNUSED,
+                       snd_pcm_uframes_t src_offset ATTRIBUTE_UNUSED,
                        const snd_pcm_channel_area_t *dst_area,
-                       size_t dst_offset,
-                       size_t frames,
+                       snd_pcm_uframes_t dst_offset,
+                       snd_pcm_uframes_t frames,
                        const ttable_dst_t* ttable ATTRIBUTE_UNUSED,
                        const route_params_t *params)
 {
@@ -105,10 +105,10 @@ static void route1_zero(const snd_pcm_channel_area_t *src_areas ATTRIBUTE_UNUSED
 }
 
 static void route1_one(const snd_pcm_channel_area_t *src_areas,
-                      size_t src_offset,
+                      snd_pcm_uframes_t src_offset,
                       const snd_pcm_channel_area_t *dst_area,
-                      size_t dst_offset,
-                      size_t frames,
+                      snd_pcm_uframes_t dst_offset,
+                      snd_pcm_uframes_t frames,
                       const ttable_dst_t* ttable,
                       const route_params_t *params)
 {
@@ -150,10 +150,10 @@ static void route1_one(const snd_pcm_channel_area_t *src_areas,
 }
 
 static void route1_many(const snd_pcm_channel_area_t *src_areas,
-                       size_t src_offset,
+                       snd_pcm_uframes_t src_offset,
                        const snd_pcm_channel_area_t *dst_area,
-                       size_t dst_offset,
-                       size_t frames,
+                       snd_pcm_uframes_t dst_offset,
+                       snd_pcm_uframes_t frames,
                        const ttable_dst_t* ttable,
                        const route_params_t *params)
 {
@@ -383,14 +383,14 @@ static void route1_many(const snd_pcm_channel_area_t *src_areas,
 }
 
 static void route_transfer(const snd_pcm_channel_area_t *src_areas,
-                          size_t src_offset,
+                          snd_pcm_uframes_t src_offset,
                           const snd_pcm_channel_area_t *dst_areas,
-                          size_t dst_offset,
-                          size_t dst_channels,
-                          size_t frames,
+                          snd_pcm_uframes_t dst_offset,
+                          snd_pcm_uframes_t dst_channels,
+                          snd_pcm_uframes_t frames,
                           route_params_t *params)
 {
-       size_t dst_channel;
+       unsigned int dst_channel;
        ttable_dst_t *dstp;
        const snd_pcm_channel_area_t *dst_area;
 
@@ -411,7 +411,7 @@ static int snd_pcm_route_close(snd_pcm_t *pcm)
        snd_pcm_route_t *route = pcm->private;
        route_params_t *params = &route->params;
        int err = 0;
-       size_t dst_channel;
+       unsigned int dst_channel;
        if (route->plug.close_slave)
                err = snd_pcm_close(route->plug.slave);
        if (params->dsts) {
@@ -430,56 +430,63 @@ static int snd_pcm_route_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
        snd_pcm_route_t *route = pcm->private;
        snd_pcm_t *slave = route->plug.slave;
        int err;
+       unsigned int cmask, lcmask;
        snd_pcm_hw_params_t sparams;
        unsigned int links = (SND_PCM_HW_PARBIT_RATE |
-                             SND_PCM_HW_PARBIT_FRAGMENTS |
-                             SND_PCM_HW_PARBIT_FRAGMENT_SIZE |
-                             SND_PCM_HW_PARBIT_FRAGMENT_LENGTH |
+                             SND_PCM_HW_PARBIT_PERIODS |
+                             SND_PCM_HW_PARBIT_PERIOD_SIZE |
+                             SND_PCM_HW_PARBIT_PERIOD_TIME |
                              SND_PCM_HW_PARBIT_BUFFER_SIZE |
-                             SND_PCM_HW_PARBIT_BUFFER_LENGTH);
+                             SND_PCM_HW_PARBIT_BUFFER_TIME |
+                             SND_PCM_HW_PARBIT_TICK_TIME);
        mask_t *access_mask = alloca(mask_sizeof());
        mask_t *format_mask = alloca(mask_sizeof());
        mask_t *saccess_mask = alloca(mask_sizeof());
        mask_load(access_mask, SND_PCM_ACCBIT_PLUGIN);
        mask_load(format_mask, SND_PCM_FMTBIT_LINEAR);
        mask_load(saccess_mask, SND_PCM_ACCBIT_MMAP);
-       err = _snd_pcm_hw_param_mask(params, 1, SND_PCM_HW_PARAM_ACCESS,
+       cmask = params->cmask;
+       params->cmask = 0;
+       err = _snd_pcm_hw_param_mask(params, SND_PCM_HW_PARAM_ACCESS,
                                      access_mask);
        if (err < 0)
                return err;
-       err = _snd_pcm_hw_param_mask(params, 1, SND_PCM_HW_PARAM_FORMAT,
+       err = _snd_pcm_hw_param_mask(params, SND_PCM_HW_PARAM_FORMAT,
                                      format_mask);
        if (err < 0)
                return err;
-       err = _snd_pcm_hw_param_min(params, 1, SND_PCM_HW_PARAM_CHANNELS, 1);
+       err = _snd_pcm_hw_param_min(params, SND_PCM_HW_PARAM_CHANNELS, 1, 0);
        if (err < 0)
                return err;
+       lcmask = params->cmask;
+       params->cmask |= cmask;
 
        _snd_pcm_hw_params_any(&sparams);
-       _snd_pcm_hw_param_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
+       _snd_pcm_hw_param_mask(&sparams, SND_PCM_HW_PARAM_ACCESS,
                                saccess_mask);
        if (route->sformat >= 0) {
-               _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_FORMAT,
-                                      route->sformat);
-               _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_SUBFORMAT,
-                                      SND_PCM_SUBFORMAT_STD);
+               _snd_pcm_hw_param_set(&sparams, SND_PCM_HW_PARAM_FORMAT,
+                                     route->sformat, 0);
+               _snd_pcm_hw_param_set(&sparams, SND_PCM_HW_PARAM_SUBFORMAT,
+                                     SND_PCM_SUBFORMAT_STD, 0);
        } else
                links |= (SND_PCM_HW_PARBIT_FORMAT | 
                          SND_PCM_HW_PARBIT_SUBFORMAT |
                          SND_PCM_HW_PARBIT_SAMPLE_BITS);
        if (route->schannels >= 0) {
-               _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_CHANNELS,
-                                      route->schannels);
+               _snd_pcm_hw_param_set(&sparams, SND_PCM_HW_PARAM_CHANNELS,
+                                     route->schannels, 0);
        } else {
                links |= SND_PCM_HW_PARBIT_CHANNELS;
                if (route->sformat < 0)
                        links |= (SND_PCM_HW_PARBIT_FRAME_BITS |
-                                 SND_PCM_HW_PARBIT_FRAGMENT_BYTES |
+                                 SND_PCM_HW_PARBIT_PERIOD_BYTES |
                                  SND_PCM_HW_PARBIT_BUFFER_BYTES);
        }
                
        err = snd_pcm_hw_refine2(params, &sparams,
-                                snd_pcm_hw_refine, slave, links);
+                                snd_pcm_generic_hw_link, slave, links);
+       params->cmask |= lcmask;
        if (err < 0)
                return err;
        params->info &= ~(SND_PCM_INFO_MMAP | SND_PCM_INFO_MMAP_VALID);
@@ -492,49 +499,56 @@ static int snd_pcm_route_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
        snd_pcm_t *slave = route->plug.slave;
        int err;
        snd_pcm_hw_params_t sparams;
-       unsigned int links = (SND_PCM_HW_PARBIT_FRAGMENTS |
-                             SND_PCM_HW_PARBIT_FRAGMENT_SIZE |
-                             SND_PCM_HW_PARBIT_FRAGMENT_LENGTH |
+       unsigned int links = (SND_PCM_HW_PARBIT_PERIODS |
+                             SND_PCM_HW_PARBIT_PERIOD_SIZE |
+                             SND_PCM_HW_PARBIT_PERIOD_TIME |
                              SND_PCM_HW_PARBIT_BUFFER_SIZE |
-                             SND_PCM_HW_PARBIT_BUFFER_LENGTH);
+                             SND_PCM_HW_PARBIT_BUFFER_TIME |
+                             SND_PCM_HW_PARBIT_TICK_TIME);
        unsigned int src_format, dst_format;
        mask_t *saccess_mask = alloca(mask_sizeof());
        mask_load(saccess_mask, SND_PCM_ACCBIT_MMAP);
 
        _snd_pcm_hw_params_any(&sparams);
-       _snd_pcm_hw_param_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
+       _snd_pcm_hw_param_mask(&sparams, SND_PCM_HW_PARAM_ACCESS,
                                saccess_mask);
        if (route->sformat >= 0) {
-               _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_FORMAT,
-                                      route->sformat);
-               _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_SUBFORMAT,
-                                      SND_PCM_SUBFORMAT_STD);
+               _snd_pcm_hw_param_set(&sparams, SND_PCM_HW_PARAM_FORMAT,
+                                     route->sformat, 0);
+               _snd_pcm_hw_param_set(&sparams, SND_PCM_HW_PARAM_SUBFORMAT,
+                                     SND_PCM_SUBFORMAT_STD, 0);
        } else
                links |= (SND_PCM_HW_PARBIT_FORMAT | 
                          SND_PCM_HW_PARBIT_SUBFORMAT |
                          SND_PCM_HW_PARBIT_SAMPLE_BITS);
        if (route->schannels >= 0) {
-               _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_CHANNELS,
-                                     route->schannels);
+               _snd_pcm_hw_param_set(&sparams, SND_PCM_HW_PARAM_CHANNELS,
+                                     route->schannels, 0);
        } else {
                links |= SND_PCM_HW_PARBIT_CHANNELS;
                if (route->sformat < 0)
                        links |= (SND_PCM_HW_PARBIT_FRAME_BITS |
-                                 SND_PCM_HW_PARBIT_FRAGMENT_BYTES |
+                                 SND_PCM_HW_PARBIT_PERIOD_BYTES |
                                  SND_PCM_HW_PARBIT_BUFFER_BYTES);
        }
 
-       err = snd_pcm_hw_params2(params, &sparams, 
-                                snd_pcm_hw_params, slave, links);
+       err = snd_pcm_hw_params_refine(&sparams, links, params);
+       assert(err >= 0);
+       err = _snd_pcm_hw_refine(&sparams);
+       assert(err >= 0);
+       err = snd_pcm_hw_params(slave, &sparams);
+       params->cmask = 0;
+       sparams.cmask = ~0U;
+       snd_pcm_hw_params_refine(params, links, &sparams);
        if (err < 0)
                return err;
        params->info &= ~(SND_PCM_INFO_MMAP | SND_PCM_INFO_MMAP_VALID);
        if (pcm->stream == SND_PCM_STREAM_PLAYBACK) {
-               src_format = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FORMAT);
+               src_format = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FORMAT, 0);
                dst_format = slave->format;
        } else {
                src_format = slave->format;
-               dst_format = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FORMAT);
+               dst_format = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FORMAT, 0);
        }
        route->params.get_idx = get_index(src_format, SND_PCM_FORMAT_U16);
        route->params.put_idx = put_index(SND_PCM_FORMAT_U32, dst_format);
@@ -552,28 +566,28 @@ static int snd_pcm_route_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
        return 0;
 }
 
-static ssize_t snd_pcm_route_write_areas(snd_pcm_t *pcm,
+static snd_pcm_sframes_t snd_pcm_route_write_areas(snd_pcm_t *pcm,
                                         const snd_pcm_channel_area_t *areas,
-                                        size_t offset,
-                                        size_t size,
-                                        size_t *slave_sizep)
+                                        snd_pcm_uframes_t offset,
+                                        snd_pcm_uframes_t size,
+                                        snd_pcm_uframes_t *slave_sizep)
 {
        snd_pcm_route_t *route = pcm->private;
        snd_pcm_t *slave = route->plug.slave;
-       size_t xfer = 0;
-       ssize_t err = 0;
+       snd_pcm_uframes_t xfer = 0;
+       snd_pcm_sframes_t err = 0;
        if (slave_sizep && *slave_sizep < size)
                size = *slave_sizep;
        assert(size > 0);
        while (xfer < size) {
-               size_t frames = snd_pcm_mmap_playback_xfer(slave, size - xfer);
+               snd_pcm_uframes_t frames = snd_pcm_mmap_playback_xfer(slave, size - xfer);
                route_transfer(areas, offset, 
                               snd_pcm_mmap_areas(slave), snd_pcm_mmap_offset(slave),
                               slave->channels, frames, &route->params);
                err = snd_pcm_mmap_forward(slave, frames);
                if (err < 0)
                        break;
-               assert((size_t)err == frames);
+               assert((snd_pcm_uframes_t)err == frames);
                offset += err;
                xfer += err;
                snd_pcm_mmap_hw_forward(pcm, err);
@@ -586,28 +600,28 @@ static ssize_t snd_pcm_route_write_areas(snd_pcm_t *pcm,
        return err;
 }
 
-static ssize_t snd_pcm_route_read_areas(snd_pcm_t *pcm,
+static snd_pcm_sframes_t snd_pcm_route_read_areas(snd_pcm_t *pcm,
                                         const snd_pcm_channel_area_t *areas,
-                                        size_t offset,
-                                        size_t size,
-                                        size_t *slave_sizep)
+                                        snd_pcm_uframes_t offset,
+                                        snd_pcm_uframes_t size,
+                                        snd_pcm_uframes_t *slave_sizep)
 {
        snd_pcm_route_t *route = pcm->private;
        snd_pcm_t *slave = route->plug.slave;
-       size_t xfer = 0;
-       ssize_t err = 0;
+       snd_pcm_uframes_t xfer = 0;
+       snd_pcm_sframes_t err = 0;
        if (slave_sizep && *slave_sizep < size)
                size = *slave_sizep;
        assert(size > 0);
        while (xfer < size) {
-               size_t frames = snd_pcm_mmap_capture_xfer(slave, size - xfer);
+               snd_pcm_uframes_t frames = snd_pcm_mmap_capture_xfer(slave, size - xfer);
                route_transfer(snd_pcm_mmap_areas(slave), snd_pcm_mmap_offset(slave),
                               areas, offset, 
                               pcm->channels, frames, &route->params);
                err = snd_pcm_mmap_forward(slave, frames);
                if (err < 0)
                        break;
-               assert((size_t)err == frames);
+               assert((snd_pcm_uframes_t)err == frames);
                offset += err;
                xfer += err;
                snd_pcm_mmap_hw_forward(pcm, err);
index e649ffdfd5b5dc9ec2fef27e2922d3e2a99c70a2..ef7ac47e52294f5c08d811ce845fd602afc2b59a 100644 (file)
@@ -69,16 +69,16 @@ typedef struct {
        snd_pcm_t *pcm;
        int format;
        int rate;
-       size_t channels_count;
-       size_t open_count;
-       size_t setup_count;
-       size_t mmap_count;
-       size_t prepared_count;
-       size_t running_count;
-       size_t safety_threshold;
-       size_t silence_frames;
+       unsigned int channels_count;
+       unsigned int open_count;
+       unsigned int setup_count;
+       unsigned int mmap_count;
+       unsigned int prepared_count;
+       unsigned int running_count;
+       snd_pcm_uframes_t safety_threshold;
+       snd_pcm_uframes_t silence_frames;
        snd_pcm_sw_params_t sw_params;
-       size_t hw_ptr;
+       snd_pcm_uframes_t hw_ptr;
        int poll[2];
        int polling;
        pthread_t thread;
@@ -91,18 +91,18 @@ typedef struct {
        struct list_head list;
        snd_pcm_t *pcm;
        snd_pcm_share_slave_t *slave;
-       size_t channels_count;
+       unsigned int channels_count;
        int *slave_channels;
        int xfer_mode;
        int xrun_mode;
-       size_t avail_min;
+       snd_pcm_uframes_t avail_min;
        int async_sig;
        pid_t async_pid;
        int drain_silenced;
        struct timeval trigger_time;
        int state;
-       size_t hw_ptr;
-       size_t appl_ptr;
+       snd_pcm_uframes_t hw_ptr;
+       snd_pcm_uframes_t appl_ptr;
        int ready;
        int client_socket;
        int slave_socket;
@@ -110,9 +110,9 @@ typedef struct {
 
 static void _snd_pcm_share_stop(snd_pcm_t *pcm, int state);
 
-static size_t snd_pcm_share_slave_avail(snd_pcm_share_slave_t *slave)
+static snd_pcm_uframes_t snd_pcm_share_slave_avail(snd_pcm_share_slave_t *slave)
 {
-       ssize_t avail;
+       snd_pcm_sframes_t avail;
        snd_pcm_t *pcm = slave->pcm;
        avail = slave->hw_ptr - *pcm->appl_ptr;
        if (pcm->stream == SND_PCM_STREAM_PLAYBACK)
@@ -124,15 +124,15 @@ static size_t snd_pcm_share_slave_avail(snd_pcm_share_slave_t *slave)
 
 /* Warning: take the mutex before to call this */
 /* Return number of frames to mmap_forward the slave */
-static size_t _snd_pcm_share_slave_forward(snd_pcm_share_slave_t *slave)
+static snd_pcm_uframes_t _snd_pcm_share_slave_forward(snd_pcm_share_slave_t *slave)
 {
        struct list_head *i;
-       size_t buffer_size, boundary;
-       size_t slave_appl_ptr;
-       ssize_t frames, safety_frames;
-       ssize_t min_frames, max_frames;
-       size_t avail, slave_avail;
-       size_t slave_hw_avail;
+       snd_pcm_uframes_t buffer_size, boundary;
+       snd_pcm_uframes_t slave_appl_ptr;
+       snd_pcm_sframes_t frames, safety_frames;
+       snd_pcm_sframes_t min_frames, max_frames;
+       snd_pcm_uframes_t avail, slave_avail;
+       snd_pcm_uframes_t slave_hw_avail;
        slave_avail = snd_pcm_share_slave_avail(slave);
        boundary = slave->pcm->boundary;
        buffer_size = slave->pcm->buffer_size;
@@ -187,17 +187,17 @@ static size_t _snd_pcm_share_slave_forward(snd_pcm_share_slave_t *slave)
    - draining silencing
    - return distance in frames to next event
 */
-static size_t _snd_pcm_share_missing(snd_pcm_t *pcm, int slave_xrun)
+static snd_pcm_uframes_t _snd_pcm_share_missing(snd_pcm_t *pcm, int slave_xrun)
 {
        snd_pcm_share_t *share = pcm->private;
        snd_pcm_share_slave_t *slave = share->slave;
        snd_pcm_t *spcm = slave->pcm;
-       size_t buffer_size = spcm->buffer_size;
+       snd_pcm_uframes_t buffer_size = spcm->buffer_size;
        int ready = 1, running = 0;
-       size_t avail = 0, slave_avail;
-       ssize_t hw_avail;
-       size_t missing = INT_MAX;
-       ssize_t ready_missing;
+       snd_pcm_uframes_t avail = 0, slave_avail;
+       snd_pcm_sframes_t hw_avail;
+       snd_pcm_uframes_t missing = INT_MAX;
+       snd_pcm_sframes_t ready_missing;
        //      printf("state=%d hw_ptr=%d appl_ptr=%d slave appl_ptr=%d safety=%d silence=%d\n", share->state, slave->hw_ptr, share->appl_ptr, *slave->pcm->appl_ptr, slave->safety_threshold, slave->silence_frames);
        switch (share->state) {
        case SND_PCM_STATE_RUNNING:
@@ -219,11 +219,11 @@ static size_t _snd_pcm_share_missing(snd_pcm_t *pcm, int slave_xrun)
        slave_avail = snd_pcm_share_slave_avail(slave);
        if (avail < slave_avail) {
                /* Some frames need still to be transferred */
-               ssize_t slave_hw_avail = buffer_size - slave_avail;
-               ssize_t safety_missing = slave_hw_avail - slave->safety_threshold;
+               snd_pcm_sframes_t slave_hw_avail = buffer_size - slave_avail;
+               snd_pcm_sframes_t safety_missing = slave_hw_avail - slave->safety_threshold;
                if (safety_missing < 0) {
-                       ssize_t err;
-                       ssize_t frames = slave_avail - avail;
+                       snd_pcm_sframes_t err;
+                       snd_pcm_sframes_t frames = slave_avail - avail;
                        if (-safety_missing <= frames) {
                                frames = -safety_missing;
                                missing = 1;
@@ -245,7 +245,7 @@ static size_t _snd_pcm_share_missing(snd_pcm_t *pcm, int slave_xrun)
                                _snd_pcm_share_stop(pcm, SND_PCM_STATE_SETUP);
                                break;
                        }
-                       if ((size_t)hw_avail < missing)
+                       if ((snd_pcm_uframes_t)hw_avail < missing)
                                missing = hw_avail;
                        running = 1;
                        ready = 0;
@@ -257,13 +257,13 @@ static size_t _snd_pcm_share_missing(snd_pcm_t *pcm, int slave_xrun)
                                _snd_pcm_share_stop(pcm, SND_PCM_STATE_XRUN);
                                break;
                        }
-                       if ((size_t)hw_avail < missing)
+                       if ((snd_pcm_uframes_t)hw_avail < missing)
                                missing = hw_avail;
                }
                ready_missing = share->avail_min - avail;
                if (ready_missing > 0) {
                        ready = 0;
-                       if ((size_t)ready_missing < missing)
+                       if ((snd_pcm_uframes_t)ready_missing < missing)
                                missing = ready_missing;
                }
                running = 1;
@@ -293,12 +293,12 @@ static size_t _snd_pcm_share_missing(snd_pcm_t *pcm, int slave_xrun)
            !share->drain_silenced) {
                /* drain silencing */
                if (avail >= slave->silence_frames) {
-                       size_t offset = share->appl_ptr % buffer_size;
-                       size_t xfer = 0;
-                       size_t size = slave->silence_frames;
+                       snd_pcm_uframes_t offset = share->appl_ptr % buffer_size;
+                       snd_pcm_uframes_t xfer = 0;
+                       snd_pcm_uframes_t size = slave->silence_frames;
                        while (xfer < size) {
-                               size_t frames = size - xfer;
-                               size_t cont = buffer_size - offset;
+                               snd_pcm_uframes_t frames = size - xfer;
+                               snd_pcm_uframes_t cont = buffer_size - offset;
                                if (cont < frames)
                                        frames = cont;
                                snd_pcm_areas_silence(pcm->running_areas, offset, pcm->channels, frames, pcm->format);
@@ -309,7 +309,7 @@ static size_t _snd_pcm_share_missing(snd_pcm_t *pcm, int slave_xrun)
                        }
                        share->drain_silenced = 1;
                } else {
-                       size_t silence_missing;
+                       snd_pcm_uframes_t silence_missing;
                        silence_missing = slave->silence_frames - avail;
                        if (silence_missing < missing)
                                missing = silence_missing;
@@ -319,17 +319,17 @@ static size_t _snd_pcm_share_missing(snd_pcm_t *pcm, int slave_xrun)
        return missing;
 }
 
-static size_t _snd_pcm_share_slave_missing(snd_pcm_share_slave_t *slave)
+static snd_pcm_uframes_t _snd_pcm_share_slave_missing(snd_pcm_share_slave_t *slave)
 {
-       size_t missing = INT_MAX;
+       snd_pcm_uframes_t missing = INT_MAX;
        struct list_head *i;
-       ssize_t avail = snd_pcm_avail_update(slave->pcm);
+       snd_pcm_sframes_t avail = snd_pcm_avail_update(slave->pcm);
        int slave_xrun = (avail == -EPIPE);
        slave->hw_ptr = *slave->pcm->hw_ptr;
        for (i = slave->clients.next; i != &slave->clients; i = i->next) {
                snd_pcm_share_t *share = list_entry(i, snd_pcm_share_t, list);
                snd_pcm_t *pcm = share->pcm;
-               size_t m = _snd_pcm_share_missing(pcm, slave_xrun);
+               snd_pcm_uframes_t m = _snd_pcm_share_missing(pcm, slave_xrun);
                if (m < missing)
                        missing = m;
        }
@@ -350,25 +350,25 @@ void *snd_pcm_share_slave_thread(void *data)
        err = pipe(slave->poll);
        assert(err >= 0);
        while (slave->open_count > 0) {
-               size_t missing;
+               snd_pcm_uframes_t missing;
                //              printf("begin min_missing\n");
                missing = _snd_pcm_share_slave_missing(slave);
                //              printf("min_missing=%d\n", missing);
                if (missing < INT_MAX) {
-                       size_t hw_ptr;
-                       ssize_t avail_min;
+                       snd_pcm_uframes_t hw_ptr;
+                       snd_pcm_sframes_t avail_min;
                        hw_ptr = slave->hw_ptr + missing;
-                       hw_ptr += spcm->fragment_size - 1;
+                       hw_ptr += spcm->period_size - 1;
                        if (hw_ptr >= spcm->boundary)
                                hw_ptr -= spcm->boundary;
-                       hw_ptr -= hw_ptr % spcm->fragment_size;
+                       hw_ptr -= hw_ptr % spcm->period_size;
                        avail_min = hw_ptr - *spcm->appl_ptr;
                        if (spcm->stream == SND_PCM_STREAM_PLAYBACK)
                                avail_min += spcm->buffer_size;
                        if (avail_min < 0)
                                avail_min += spcm->boundary;
                        // printf("avail_min=%d\n", avail_min);
-                       if ((size_t)avail_min != spcm->avail_min) {
+                       if ((snd_pcm_uframes_t)avail_min != spcm->avail_min) {
                                snd_pcm_sw_param_near(spcm, &slave->sw_params, SND_PCM_SW_PARAM_AVAIL_MIN, avail_min);
                                err = snd_pcm_sw_params(spcm, &slave->sw_params);
                                assert(err >= 0);
@@ -395,8 +395,8 @@ static void _snd_pcm_share_update(snd_pcm_t *pcm)
        snd_pcm_share_t *share = pcm->private;
        snd_pcm_share_slave_t *slave = share->slave;
        snd_pcm_t *spcm = slave->pcm;
-       size_t missing;
-       ssize_t avail = snd_pcm_avail_update(spcm);
+       snd_pcm_uframes_t missing;
+       snd_pcm_sframes_t avail = snd_pcm_avail_update(spcm);
        slave->hw_ptr = *slave->pcm->hw_ptr;
        missing = _snd_pcm_share_missing(pcm, avail == -EPIPE);
        if (!slave->polling) {
@@ -404,20 +404,20 @@ static void _snd_pcm_share_update(snd_pcm_t *pcm)
                return;
        }
        if (missing < INT_MAX) {
-               size_t hw_ptr;
-               ssize_t avail_min;
+               snd_pcm_uframes_t hw_ptr;
+               snd_pcm_sframes_t avail_min;
                int err;
                hw_ptr = slave->hw_ptr + missing;
-               hw_ptr += spcm->fragment_size - 1;
+               hw_ptr += spcm->period_size - 1;
                if (hw_ptr >= spcm->boundary)
                        hw_ptr -= spcm->boundary;
-               hw_ptr -= hw_ptr % spcm->fragment_size;
+               hw_ptr -= hw_ptr % spcm->period_size;
                avail_min = hw_ptr - *spcm->appl_ptr;
                if (spcm->stream == SND_PCM_STREAM_PLAYBACK)
                        avail_min += spcm->buffer_size;
                if (avail_min < 0)
                        avail_min += spcm->boundary;
-               if ((size_t)avail_min < spcm->avail_min) {
+               if ((snd_pcm_uframes_t)avail_min < spcm->avail_min) {
                        snd_pcm_sw_param_near(spcm, &slave->sw_params, SND_PCM_SW_PARAM_AVAIL_MIN, avail_min);
                        err = snd_pcm_sw_params(spcm, &slave->sw_params);
                        assert(err >= 0);
@@ -461,57 +461,64 @@ static int snd_pcm_share_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
        snd_pcm_share_slave_t *slave = share->slave;
        snd_pcm_hw_params_t sparams;
        int err;
+       unsigned int cmask, lcmask;
        mask_t *access_mask = alloca(mask_sizeof());
        const mask_t *mmap_mask;
        mask_t *saccess_mask = alloca(mask_sizeof());
        mask_load(saccess_mask, SND_PCM_ACCBIT_MMAP);
 
-       err = _snd_pcm_hw_param_set(params, 1, SND_PCM_HW_PARAM_CHANNELS,
-                                    share->channels_count);
+       cmask = params->cmask;
+       params->cmask = 0;
+       err = _snd_pcm_hw_param_set(params, SND_PCM_HW_PARAM_CHANNELS,
+                                   share->channels_count, 0);
        if (err < 0)
                return err;
 
        if (slave->format >= 0) {
-               err = _snd_pcm_hw_param_set(params, 1, SND_PCM_HW_PARAM_FORMAT,
-                                            slave->format);
+               err = _snd_pcm_hw_param_set(params, SND_PCM_HW_PARAM_FORMAT,
+                                           slave->format, 0);
                if (err < 0)
                        return err;
        }
 
        if (slave->rate >= 0) {
-               err = _snd_pcm_hw_param_set(params, 1, SND_PCM_HW_PARAM_RATE,
-                                            slave->rate);
+               err = _snd_pcm_hw_param_set(params, SND_PCM_HW_PARAM_RATE,
+                                           slave->rate, 0);
                if (err < 0)
                        return err;
        }
+       lcmask = params->cmask;
+       params->cmask |= cmask;
 
        _snd_pcm_hw_params_any(&sparams);
-       _snd_pcm_hw_param_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
-                               saccess_mask);
-       _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_CHANNELS,
-                              slave->channels_count);
+       _snd_pcm_hw_param_mask(&sparams, SND_PCM_HW_PARAM_ACCESS,
+                              saccess_mask);
+       _snd_pcm_hw_param_set(&sparams, SND_PCM_HW_PARAM_CHANNELS,
+                             slave->channels_count, 0);
        err = snd_pcm_hw_refine2(params, &sparams,
-                                snd_pcm_hw_refine, slave->pcm,
+                                snd_pcm_generic_hw_link, slave->pcm,
                                 SND_PCM_HW_PARBIT_FORMAT |
                                 SND_PCM_HW_PARBIT_SUBFORMAT |
                                 SND_PCM_HW_PARBIT_RATE |
-                                SND_PCM_HW_PARBIT_FRAGMENT_SIZE |
-                                SND_PCM_HW_PARBIT_FRAGMENT_LENGTH |
+                                SND_PCM_HW_PARBIT_PERIOD_SIZE |
+                                SND_PCM_HW_PARBIT_PERIOD_TIME |
                                 SND_PCM_HW_PARBIT_BUFFER_SIZE |
-                                SND_PCM_HW_PARBIT_BUFFER_LENGTH |
-                                SND_PCM_HW_PARBIT_FRAGMENTS);
+                                SND_PCM_HW_PARBIT_BUFFER_TIME |
+                                SND_PCM_HW_PARBIT_PERIODS |
+                                SND_PCM_HW_PARBIT_TICK_TIME);
        if (err < 0)
                return err;
        mmap_mask = snd_pcm_hw_param_value_mask(&sparams, SND_PCM_HW_PARAM_ACCESS);
-       mask_all(access_mask);
+       mask_any(access_mask);
        mask_reset(access_mask, SND_PCM_ACCESS_MMAP_INTERLEAVED);
        if (!mask_test(mmap_mask, SND_PCM_ACCESS_MMAP_NONINTERLEAVED))
                mask_reset(access_mask, SND_PCM_ACCESS_MMAP_NONINTERLEAVED);
        if (!mask_test(mmap_mask, SND_PCM_ACCESS_MMAP_COMPLEX) &&
            !mask_test(mmap_mask, SND_PCM_ACCESS_MMAP_INTERLEAVED))
                mask_reset(access_mask, SND_PCM_ACCESS_MMAP_COMPLEX);
-       err = _snd_pcm_hw_param_mask(params, 1, SND_PCM_HW_PARAM_ACCESS,
+       err = _snd_pcm_hw_param_mask(params, SND_PCM_HW_PARAM_ACCESS,
                                      access_mask);
+       params->cmask |= lcmask;
        if (err < 0)
                return err;
        params->info |= SND_PCM_INFO_DOUBLE;
@@ -527,24 +534,29 @@ static int snd_pcm_share_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
        Pthread_mutex_lock(&slave->mutex);
        if (slave->setup_count > 1 || 
            (slave->setup_count == 1 && !pcm->setup)) {
-               err = _snd_pcm_hw_param_set(params, 1, SND_PCM_HW_PARAM_FORMAT,
-                                            spcm->format);
+               params->cmask = 0;
+               err = _snd_pcm_hw_param_set(params, SND_PCM_HW_PARAM_FORMAT,
+                                           spcm->format, 0);
                if (err < 0)
                        goto _err;
-               err = _snd_pcm_hw_param_set(params, 1, SND_PCM_HW_PARAM_SUBFORMAT,
-                                            spcm->subformat);
+               err = _snd_pcm_hw_param_set(params, SND_PCM_HW_PARAM_SUBFORMAT,
+                                           spcm->subformat, 0);
                if (err < 0)
                        goto _err;
-               err = _snd_pcm_hw_param_set(params, 1, SND_PCM_HW_PARAM_RATE,
-                                            spcm->rate);
+               err = _snd_pcm_hw_param_set(params, SND_PCM_HW_PARAM_RATE,
+                                           spcm->rate, 0);
                if (err < 0)
                        goto _err;
-               err = _snd_pcm_hw_param_set(params, 1, SND_PCM_HW_PARAM_FRAGMENT_SIZE,
-                                            spcm->fragment_size);
+               err = _snd_pcm_hw_param_set(params, SND_PCM_HW_PARAM_PERIOD_TIME,
+                                           spcm->period_time, 0);
                if (err < 0)
                        goto _err;
-               err = _snd_pcm_hw_param_set(params, 1, SND_PCM_HW_PARAM_FRAGMENTS,
-                                                  spcm->fragments);
+               err = _snd_pcm_hw_param_set(params, SND_PCM_HW_PARAM_BUFFER_SIZE,
+                                           spcm->buffer_size, 0);
+               if (err < 0)
+                       goto _err;
+               err = _snd_pcm_hw_param_set(params, SND_PCM_HW_PARAM_TICK_TIME,
+                                           spcm->tick_time, 0);
        _err:
                if (err < 0) {
                        ERR("slave is already running with different setup");
@@ -553,30 +565,38 @@ static int snd_pcm_share_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
                }
        } else {
                snd_pcm_hw_params_t sparams;
+               unsigned int links;
                mask_t *saccess_mask = alloca(mask_sizeof());
                mask_load(saccess_mask, SND_PCM_ACCBIT_MMAP);
+               links = SND_PCM_HW_PARBIT_FORMAT |
+                       SND_PCM_HW_PARBIT_SUBFORMAT |
+                       SND_PCM_HW_PARBIT_RATE |
+                       SND_PCM_HW_PARBIT_PERIOD_SIZE |
+                       SND_PCM_HW_PARBIT_PERIOD_TIME |
+                       SND_PCM_HW_PARBIT_BUFFER_SIZE |
+                       SND_PCM_HW_PARBIT_BUFFER_TIME |
+                       SND_PCM_HW_PARBIT_PERIODS |
+                       SND_PCM_HW_PARBIT_TICK_TIME;
                _snd_pcm_hw_params_any(&sparams);
-               _snd_pcm_hw_param_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
-                                       saccess_mask);
-               _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_CHANNELS,
-                                      share->channels_count);
-               err = snd_pcm_hw_params2(params, &sparams,
-                                        snd_pcm_hw_params, slave->pcm,
-                                        SND_PCM_HW_PARBIT_FORMAT |
-                                        SND_PCM_HW_PARBIT_SUBFORMAT |
-                                        SND_PCM_HW_PARBIT_RATE |
-                                        SND_PCM_HW_PARBIT_FRAGMENT_SIZE |
-                                        SND_PCM_HW_PARBIT_FRAGMENT_LENGTH |
-                                        SND_PCM_HW_PARBIT_BUFFER_SIZE |
-                                        SND_PCM_HW_PARBIT_BUFFER_LENGTH |
-                                        SND_PCM_HW_PARBIT_FRAGMENTS);
+               _snd_pcm_hw_param_mask(&sparams, SND_PCM_HW_PARAM_ACCESS,
+                                      saccess_mask);
+               _snd_pcm_hw_param_set(&sparams, SND_PCM_HW_PARAM_CHANNELS,
+                                     share->channels_count, 0);
+               err = snd_pcm_hw_params_refine(&sparams, links, params);
+               assert(err >= 0);
+               err = _snd_pcm_hw_refine(&sparams);
+               assert(err >= 0);
+               err = snd_pcm_hw_params(slave->pcm, &sparams);
+               params->cmask = 0;
+               sparams.cmask = ~0U;
+               snd_pcm_hw_params_refine(params, links, &sparams);
                if (err < 0)
                        goto _end;
                snd_pcm_sw_params_current(slave->pcm, &slave->sw_params);
                /* >= 30 ms */
                slave->safety_threshold = slave->pcm->rate * 30 / 1000;
-               slave->safety_threshold += slave->pcm->fragment_size - 1;
-               slave->safety_threshold -= slave->safety_threshold % slave->pcm->fragment_size;
+               slave->safety_threshold += slave->pcm->period_size - 1;
+               slave->safety_threshold -= slave->safety_threshold % slave->pcm->period_size;
                slave->silence_frames = slave->safety_threshold;
                if (slave->pcm->stream == SND_PCM_STREAM_PLAYBACK)
                        snd_pcm_areas_silence(slave->pcm->running_areas, 0, slave->pcm->channels, slave->pcm->buffer_size, slave->pcm->format);
@@ -598,7 +618,7 @@ static int snd_pcm_share_status(snd_pcm_t *pcm, snd_pcm_status_t *status)
        snd_pcm_share_t *share = pcm->private;
        snd_pcm_share_slave_t *slave = share->slave;
        int err = 0;
-       ssize_t sd = 0, d = 0;
+       snd_pcm_sframes_t sd = 0, d = 0;
        Pthread_mutex_lock(&slave->mutex);
        if (pcm->stream == SND_PCM_STREAM_PLAYBACK) {
                status->avail = snd_pcm_mmap_playback_avail(pcm);
@@ -630,12 +650,12 @@ static int snd_pcm_share_state(snd_pcm_t *pcm)
        return share->state;
 }
 
-static int _snd_pcm_share_delay(snd_pcm_t *pcm, ssize_t *delayp)
+static int _snd_pcm_share_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp)
 {
        snd_pcm_share_t *share = pcm->private;
        snd_pcm_share_slave_t *slave = share->slave;
        int err = 0;
-       ssize_t sd;
+       snd_pcm_sframes_t sd;
        switch (share->state) {
        case SND_PCM_STATE_XRUN:
                return -EPIPE;
@@ -655,7 +675,7 @@ static int _snd_pcm_share_delay(snd_pcm_t *pcm, ssize_t *delayp)
        return 0;
 }
 
-static int snd_pcm_share_delay(snd_pcm_t *pcm, ssize_t *delayp)
+static int snd_pcm_share_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp)
 {
        snd_pcm_share_t *share = pcm->private;
        snd_pcm_share_slave_t *slave = share->slave;
@@ -666,11 +686,11 @@ static int snd_pcm_share_delay(snd_pcm_t *pcm, ssize_t *delayp)
        return err;
 }
 
-static ssize_t snd_pcm_share_avail_update(snd_pcm_t *pcm)
+static snd_pcm_sframes_t snd_pcm_share_avail_update(snd_pcm_t *pcm)
 {
        snd_pcm_share_t *share = pcm->private;
        snd_pcm_share_slave_t *slave = share->slave;
-       ssize_t avail;
+       snd_pcm_sframes_t avail;
        Pthread_mutex_lock(&slave->mutex);
        if (share->state == SND_PCM_STATE_RUNNING) {
                avail = snd_pcm_avail_update(slave->pcm);
@@ -682,24 +702,24 @@ static ssize_t snd_pcm_share_avail_update(snd_pcm_t *pcm)
        }
        Pthread_mutex_unlock(&slave->mutex);
        avail = snd_pcm_mmap_avail(pcm);
-       if ((size_t)avail > pcm->buffer_size)
+       if ((snd_pcm_uframes_t)avail > pcm->buffer_size)
                return -EPIPE;
        return avail;
 }
 
 /* Call it with mutex held */
-static ssize_t _snd_pcm_share_mmap_forward(snd_pcm_t *pcm, size_t size)
+static snd_pcm_sframes_t _snd_pcm_share_mmap_forward(snd_pcm_t *pcm, snd_pcm_uframes_t size)
 {
        snd_pcm_share_t *share = pcm->private;
        snd_pcm_share_slave_t *slave = share->slave;
-       ssize_t ret = 0;
-       ssize_t frames;
+       snd_pcm_sframes_t ret = 0;
+       snd_pcm_sframes_t frames;
        if (pcm->stream == SND_PCM_STREAM_PLAYBACK &&
            share->state == SND_PCM_STATE_RUNNING) {
                frames = *slave->pcm->appl_ptr - share->appl_ptr;
-               if (frames > (ssize_t)pcm->buffer_size)
+               if (frames > (snd_pcm_sframes_t)pcm->buffer_size)
                        frames -= pcm->boundary;
-               else if (frames < -(ssize_t)pcm->buffer_size)
+               else if (frames < -(snd_pcm_sframes_t)pcm->buffer_size)
                        frames += pcm->boundary;
                if (frames > 0) {
                        /* Latecomer PCM */
@@ -710,9 +730,9 @@ static ssize_t _snd_pcm_share_mmap_forward(snd_pcm_t *pcm, size_t size)
        }
        snd_pcm_mmap_appl_forward(pcm, size);
        if (share->state == SND_PCM_STATE_RUNNING) {
-               ssize_t frames = _snd_pcm_share_slave_forward(slave);
+               snd_pcm_sframes_t frames = _snd_pcm_share_slave_forward(slave);
                if (frames > 0) {
-                       ssize_t err;
+                       snd_pcm_sframes_t err;
                        err = snd_pcm_mmap_forward(slave->pcm, frames);
                        assert(err == frames);
                }
@@ -721,11 +741,11 @@ static ssize_t _snd_pcm_share_mmap_forward(snd_pcm_t *pcm, size_t size)
        return size;
 }
 
-static ssize_t snd_pcm_share_mmap_forward(snd_pcm_t *pcm, size_t size)
+static snd_pcm_sframes_t snd_pcm_share_mmap_forward(snd_pcm_t *pcm, snd_pcm_uframes_t size)
 {
        snd_pcm_share_t *share = pcm->private;
        snd_pcm_share_slave_t *slave = share->slave;
-       ssize_t ret;
+       snd_pcm_sframes_t ret;
        Pthread_mutex_lock(&slave->mutex);
        ret = _snd_pcm_share_mmap_forward(pcm, size);
        Pthread_mutex_unlock(&slave->mutex);
@@ -776,14 +796,14 @@ static int snd_pcm_share_start(snd_pcm_t *pcm)
        Pthread_mutex_lock(&slave->mutex);
        share->state = SND_PCM_STATE_RUNNING;
        if (pcm->stream == SND_PCM_STREAM_PLAYBACK) {
-               size_t hw_avail = snd_pcm_mmap_playback_hw_avail(pcm);
-               size_t xfer = 0;
+               snd_pcm_uframes_t hw_avail = snd_pcm_mmap_playback_hw_avail(pcm);
+               snd_pcm_uframes_t xfer = 0;
                if (hw_avail == 0) {
                        err = -EPIPE;
                        goto _end;
                }
                if (slave->running_count) {
-                       ssize_t sd;
+                       snd_pcm_sframes_t sd;
                        err = snd_pcm_delay(slave->pcm, &sd);
                        if (err < 0)
                                goto _end;
@@ -795,9 +815,9 @@ static int snd_pcm_share_start(snd_pcm_t *pcm)
                share->hw_ptr = *slave->pcm->hw_ptr;
                share->appl_ptr = *slave->pcm->appl_ptr;
                while (xfer < hw_avail) {
-                       size_t frames = hw_avail - xfer;
-                       size_t offset = snd_pcm_mmap_offset(pcm);
-                       size_t cont = pcm->buffer_size - offset;
+                       snd_pcm_uframes_t frames = hw_avail - xfer;
+                       snd_pcm_uframes_t offset = snd_pcm_mmap_offset(pcm);
+                       snd_pcm_uframes_t cont = pcm->buffer_size - offset;
                        if (cont < frames)
                                frames = cont;
                        snd_pcm_areas_copy(pcm->stopped_areas, xfer,
@@ -841,11 +861,11 @@ static int snd_pcm_share_channel_info(snd_pcm_t *pcm, snd_pcm_channel_info_t *in
        return err;
 }
 
-static ssize_t _snd_pcm_share_rewind(snd_pcm_t *pcm, size_t frames)
+static snd_pcm_sframes_t _snd_pcm_share_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
 {
        snd_pcm_share_t *share = pcm->private;
        snd_pcm_share_slave_t *slave = share->slave;
-       ssize_t n;
+       snd_pcm_sframes_t n;
        switch (share->state) {
        case SND_PCM_STATE_RUNNING:
                break;
@@ -865,7 +885,7 @@ static ssize_t _snd_pcm_share_rewind(snd_pcm_t *pcm, size_t frames)
        n = snd_pcm_mmap_hw_avail(pcm);
        assert(n >= 0);
        if (n > 0) {
-               if ((size_t)n > frames)
+               if ((snd_pcm_uframes_t)n > frames)
                        n = frames;
                frames -= n;
        }
@@ -881,11 +901,11 @@ static ssize_t _snd_pcm_share_rewind(snd_pcm_t *pcm, size_t frames)
        return n;
 }
 
-static ssize_t snd_pcm_share_rewind(snd_pcm_t *pcm, size_t frames)
+static snd_pcm_sframes_t snd_pcm_share_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
 {
        snd_pcm_share_t *share = pcm->private;
        snd_pcm_share_slave_t *slave = share->slave;
-       ssize_t ret;
+       snd_pcm_sframes_t ret;
        Pthread_mutex_lock(&slave->mutex);
        ret = _snd_pcm_share_rewind(pcm, frames);
        Pthread_mutex_unlock(&slave->mutex);
@@ -909,7 +929,7 @@ static void _snd_pcm_share_stop(snd_pcm_t *pcm, int state)
                                   pcm->format);
        } else if (slave->running_count > 1) {
                int err;
-               ssize_t delay;
+               snd_pcm_sframes_t delay;
                snd_pcm_areas_silence(pcm->running_areas, 0, pcm->channels,
                                      pcm->buffer_size, pcm->format);
                err = snd_pcm_delay(slave->pcm, &delay);
@@ -1106,8 +1126,8 @@ snd_pcm_fast_ops_t snd_pcm_share_fast_ops = {
 
 int snd_pcm_share_open(snd_pcm_t **pcmp, char *name, char *sname,
                       int sformat, int srate,
-                      size_t schannels_count,
-                      size_t channels_count, int *channels_map,
+                      unsigned int schannels_count,
+                      unsigned int channels_count, int *channels_map,
                       int stream, int mode)
 {
        snd_pcm_t *pcm;
@@ -1291,9 +1311,9 @@ int _snd_pcm_share_open(snd_pcm_t **pcmp, char *name, snd_config_t *conf,
        int err;
        unsigned int idx;
        int *channels_map;
-       size_t channels_count = 0;
+       unsigned int channels_count = 0;
        long schannels_count = -1;
-       size_t schannel_max = 0;
+       unsigned int schannel_max = 0;
        int sformat = -1;
        long srate = -1;
        
index aecec8c69b2e7a868ce77c1412c5107868350cd7..c6b1e5bbc565833021f98c37b0e73bd4e78dccc1 100644 (file)
@@ -168,6 +168,27 @@ static int _snd_pcm_shm_hw_refine(snd_pcm_t *pcm,
        return err;
 }
 
+/* Accumulate to params->cmask */
+/* Reset sparams->cmask */
+int snd_pcm_shm_hw_link(snd_pcm_hw_params_t *params,
+                       snd_pcm_hw_params_t *sparams,
+                       snd_pcm_t *slave,
+                       unsigned long links)
+{
+       int err1, err = 0;
+       err = snd_pcm_hw_params_refine(sparams, links, params);
+       if (err >= 0) {
+               unsigned int cmask = sparams->cmask;
+               err = _snd_pcm_shm_hw_refine(slave, sparams);
+               sparams->cmask |= cmask;
+       }
+       err1 = snd_pcm_hw_params_refine(params, links, sparams);
+       if (err1 < 0)
+               err = err1;
+       sparams->cmask = 0;
+       return err;
+}
+
 static int snd_pcm_shm_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
 {
        snd_pcm_hw_params_t sparams;
@@ -178,10 +199,10 @@ static int snd_pcm_shm_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
            !mask_test(access_mask, SND_PCM_ACCESS_RW_NONINTERLEAVED))
                mask_intersect(saccess_mask, access_mask);
        _snd_pcm_hw_params_any(&sparams);
-       _snd_pcm_hw_param_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
+       _snd_pcm_hw_param_mask(&sparams, SND_PCM_HW_PARAM_ACCESS,
                                saccess_mask);
        return snd_pcm_hw_refine2(params, &sparams,
-                                 _snd_pcm_shm_hw_refine, pcm,
+                                 snd_pcm_shm_hw_link, pcm,
                                  ~SND_PCM_HW_PARBIT_ACCESS);
 }
 
@@ -201,18 +222,27 @@ static int _snd_pcm_shm_hw_params(snd_pcm_t *pcm,
 static int snd_pcm_shm_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
 {
        snd_pcm_hw_params_t sparams;
+       unsigned int links = ~SND_PCM_HW_PARBIT_ACCESS;
        const mask_t *access_mask = snd_pcm_hw_param_value_mask(params, SND_PCM_HW_PARAM_ACCESS);
        mask_t *saccess_mask = alloca(mask_sizeof());
+       int err;
        mask_load(saccess_mask, SND_PCM_ACCBIT_MMAP);
        if (!mask_test(access_mask, SND_PCM_ACCESS_RW_INTERLEAVED) &&
            !mask_test(access_mask, SND_PCM_ACCESS_RW_NONINTERLEAVED))
                mask_intersect(saccess_mask, access_mask);
        _snd_pcm_hw_params_any(&sparams);
-       _snd_pcm_hw_param_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
+       _snd_pcm_hw_param_mask(&sparams, SND_PCM_HW_PARAM_ACCESS,
                                saccess_mask);
-       return snd_pcm_hw_params2(params, &sparams,
-                                 _snd_pcm_shm_hw_params, pcm,
-                                 ~SND_PCM_HW_PARBIT_ACCESS);
+       err = snd_pcm_hw_params_refine(&sparams, links, params);
+       assert(err >= 0);
+       err = _snd_pcm_hw_refine(&sparams);
+       assert(err >= 0);
+       err = _snd_pcm_shm_hw_params(pcm, &sparams);
+       if (err < 0) {
+               snd_pcm_hw_params_refine(params, links, &sparams);
+               return err;
+       }
+       return 0;
 }
 
 static int snd_pcm_shm_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t * params)
@@ -310,7 +340,7 @@ static int snd_pcm_shm_state(snd_pcm_t *pcm)
        return snd_pcm_shm_action(pcm);
 }
 
-static int snd_pcm_shm_delay(snd_pcm_t *pcm, ssize_t *delayp)
+static int snd_pcm_shm_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp)
 {
        snd_pcm_shm_t *shm = pcm->private;
        volatile snd_pcm_shm_ctrl_t *ctrl = shm->ctrl;
@@ -323,7 +353,7 @@ static int snd_pcm_shm_delay(snd_pcm_t *pcm, ssize_t *delayp)
        return err;
 }
 
-static ssize_t snd_pcm_shm_avail_update(snd_pcm_t *pcm)
+static snd_pcm_sframes_t snd_pcm_shm_avail_update(snd_pcm_t *pcm)
 {
        snd_pcm_shm_t *shm = pcm->private;
        volatile snd_pcm_shm_ctrl_t *ctrl = shm->ctrl;
@@ -390,7 +420,7 @@ static int snd_pcm_shm_pause(snd_pcm_t *pcm, int enable)
        return snd_pcm_shm_action(pcm);
 }
 
-static ssize_t snd_pcm_shm_rewind(snd_pcm_t *pcm, size_t frames)
+static snd_pcm_sframes_t snd_pcm_shm_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
 {
        snd_pcm_shm_t *shm = pcm->private;
        volatile snd_pcm_shm_ctrl_t *ctrl = shm->ctrl;
@@ -399,7 +429,7 @@ static ssize_t snd_pcm_shm_rewind(snd_pcm_t *pcm, size_t frames)
        return snd_pcm_shm_action(pcm);
 }
 
-static ssize_t snd_pcm_shm_mmap_forward(snd_pcm_t *pcm, size_t size)
+static snd_pcm_sframes_t snd_pcm_shm_mmap_forward(snd_pcm_t *pcm, snd_pcm_uframes_t size)
 {
        snd_pcm_shm_t *shm = pcm->private;
        volatile snd_pcm_shm_ctrl_t *ctrl = shm->ctrl;
index a5b5ec95312d76a9befbdaf2363c47df47724e30..c11432acb62a8e2c92aa06a45902af1fcc2d13df 100644 (file)
@@ -245,7 +245,7 @@ int snd_rawmidi_hw_open(snd_rawmidi_t **handlep, char *name, int card, int devic
                        snd_ctl_close(ctl);
                        return ret;
                }
-               if (info.subdevice != subdevice) {
+               if (info.subdevice != (unsigned int) subdevice) {
                        close(fd);
                        goto __again;
                }