OSDN Git Service

Added error passing to some refining functions to disable abort when
authorJaroslav Kysela <perex@perex.cz>
Tue, 11 Dec 2001 15:10:27 +0000 (15:10 +0000)
committerJaroslav Kysela <perex@perex.cz>
Tue, 11 Dec 2001 15:10:27 +0000 (15:10 +0000)
no configuration can be found.

src/pcm/pcm.c
src/pcm/pcm_local.h
src/pcm/pcm_params.c
src/pcm/pcm_plug.c

index 4f33c5d..bb6e53b 100644 (file)
@@ -2287,6 +2287,17 @@ int snd_pcm_access_mask_test(const snd_pcm_access_mask_t *mask, snd_pcm_access_t
 }
 
 /**
+ * \brief test, if given a #snd_pcm_access_mask_t is empty
+ * \param mask pointer to mask
+ * \retval 0 not empty
+ * \retval 1 empty
+ */
+int snd_pcm_access_mask_empty(const snd_pcm_access_mask_t *mask)
+{
+       return snd_mask_empty((const snd_mask_t *) mask);
+}
+
+/**
  * \brief make an access type present in a #snd_pcm_access_mask_t
  * \param mask pointer to mask
  * \param val access type
@@ -2597,7 +2608,11 @@ int snd_pcm_hw_params_set_access(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, sn
  */
 snd_pcm_access_t snd_pcm_hw_params_set_access_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
 {
-       return snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_ACCESS, NULL);
+       unsigned int res;
+
+       if (snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_ACCESS, NULL, &res) < 0)
+               return 0;
+       return res;
 }
 
 /**
@@ -2608,7 +2623,11 @@ snd_pcm_access_t snd_pcm_hw_params_set_access_first(snd_pcm_t *pcm, snd_pcm_hw_p
  */
 snd_pcm_access_t snd_pcm_hw_params_set_access_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
 {
-       return snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_ACCESS, NULL);
+       unsigned int res;
+
+       if (snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_ACCESS, NULL, &res) < 0)
+               return 0;
+       return res;
 }
 
 /**
@@ -2676,7 +2695,11 @@ int snd_pcm_hw_params_set_format(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, sn
  */
 snd_pcm_format_t snd_pcm_hw_params_set_format_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
 {
-       return snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_FORMAT, NULL);
+       unsigned int res;
+       
+       if (snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_FORMAT, NULL, &res) < 0)
+               return 0;
+       return res;
 }
 
 /**
@@ -2687,7 +2710,11 @@ snd_pcm_format_t snd_pcm_hw_params_set_format_first(snd_pcm_t *pcm, snd_pcm_hw_p
  */
 snd_pcm_format_t snd_pcm_hw_params_set_format_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
 {
-       return snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_FORMAT, NULL);
+       unsigned int res;
+
+       if (snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_FORMAT, NULL, &res) < 0)
+               return 0;
+       return res;
 }
 
 /**
@@ -2755,7 +2782,11 @@ int snd_pcm_hw_params_set_subformat(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
  */
 snd_pcm_subformat_t snd_pcm_hw_params_set_subformat_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
 {
-       return snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_SUBFORMAT, NULL);
+       unsigned int res;
+       
+       if (snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_SUBFORMAT, NULL, &res) < 0)
+               return 0;
+       return res;
 }
 
 /**
@@ -2766,7 +2797,11 @@ snd_pcm_subformat_t snd_pcm_hw_params_set_subformat_first(snd_pcm_t *pcm, snd_pc
  */
 snd_pcm_subformat_t snd_pcm_hw_params_set_subformat_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
 {
-       return snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_SUBFORMAT, NULL);
+       unsigned int res;
+
+       if (snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_SUBFORMAT, NULL, &res) < 0)
+               return 0;
+       return res;
 }
 
 /**
@@ -2892,7 +2927,11 @@ int snd_pcm_hw_params_set_channels_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *p
  */
 unsigned int snd_pcm_hw_params_set_channels_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val)
 {
-       return snd_pcm_hw_param_set_near(pcm, params, SND_PCM_HW_PARAM_CHANNELS, val, NULL);
+       unsigned int res;
+
+       if (snd_pcm_hw_param_set_near(pcm, params, SND_PCM_HW_PARAM_CHANNELS, val, NULL, &res) < 0)
+               return 0;
+       return res;
 }
 
 /**
@@ -2903,7 +2942,11 @@ unsigned int snd_pcm_hw_params_set_channels_near(snd_pcm_t *pcm, snd_pcm_hw_para
  */
 unsigned int snd_pcm_hw_params_set_channels_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
 {
-       return snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_CHANNELS, NULL);
+       unsigned int res;
+       
+       if (snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_CHANNELS, NULL, &res) < 0)
+               return 0;
+       return res;
 }
 
 /**
@@ -2914,7 +2957,11 @@ unsigned int snd_pcm_hw_params_set_channels_first(snd_pcm_t *pcm, snd_pcm_hw_par
  */
 unsigned int snd_pcm_hw_params_set_channels_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
 {
-       return snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_CHANNELS, NULL);
+       unsigned int res;
+
+       if (snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_CHANNELS, NULL, &res) < 0)
+               return 0;
+       return res;
 }
 
 
@@ -3045,7 +3092,11 @@ int snd_pcm_hw_params_set_rate_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *param
  */
 unsigned int snd_pcm_hw_params_set_rate_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int *dir)
 {
-       return snd_pcm_hw_param_set_near(pcm, params, SND_PCM_HW_PARAM_RATE, val, dir);
+       unsigned int res;
+
+       if (snd_pcm_hw_param_set_near(pcm, params, SND_PCM_HW_PARAM_RATE, val, dir, &res) < 0)
+               return 0;
+       return res;
 }
 
 /**
@@ -3059,7 +3110,11 @@ unsigned int snd_pcm_hw_params_set_rate_near(snd_pcm_t *pcm, snd_pcm_hw_params_t
  */
 unsigned int snd_pcm_hw_params_set_rate_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir)
 {
-       return snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_RATE, dir);
+       unsigned int res;
+       
+       if (snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_RATE, dir, &res) < 0)
+               return 0;
+       return res;
 }
 
 /**
@@ -3073,7 +3128,11 @@ unsigned int snd_pcm_hw_params_set_rate_first(snd_pcm_t *pcm, snd_pcm_hw_params_
  */
 unsigned int snd_pcm_hw_params_set_rate_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir)
 {
-       return snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_RATE, dir);
+       unsigned int res;
+
+       if (snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_RATE, dir, &res) < 0)
+               return 0;
+       return res;
 }
 
 
@@ -3205,7 +3264,11 @@ int snd_pcm_hw_params_set_period_time_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t
  */
 unsigned int snd_pcm_hw_params_set_period_time_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int *dir)
 {
-       return snd_pcm_hw_param_set_near(pcm, params, SND_PCM_HW_PARAM_PERIOD_TIME, val, dir);
+       unsigned int res;
+
+       if (snd_pcm_hw_param_set_near(pcm, params, SND_PCM_HW_PARAM_PERIOD_TIME, val, dir, &res) < 0)
+               return 0;
+       return res;
 }
 
 /**
@@ -3219,7 +3282,11 @@ unsigned int snd_pcm_hw_params_set_period_time_near(snd_pcm_t *pcm, snd_pcm_hw_p
  */
 unsigned int snd_pcm_hw_params_set_period_time_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir)
 {
-       return snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_PERIOD_TIME, dir);
+       unsigned int res;
+       
+       if (snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_PERIOD_TIME, dir, &res) < 0)
+               return 0;
+       return res;
 }
 
 /**
@@ -3233,7 +3300,11 @@ unsigned int snd_pcm_hw_params_set_period_time_first(snd_pcm_t *pcm, snd_pcm_hw_
  */
 unsigned int snd_pcm_hw_params_set_period_time_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir)
 {
-       return snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_PERIOD_TIME, dir);
+       unsigned int res;
+
+       if (snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_PERIOD_TIME, dir, &res) < 0)
+               return 0;
+       return res;
 }
 
 
@@ -3375,7 +3446,11 @@ int snd_pcm_hw_params_set_period_size_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t
  */
 snd_pcm_uframes_t snd_pcm_hw_params_set_period_size_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val, int *dir)
 {
-       return snd_pcm_hw_param_set_near(pcm, params, SND_PCM_HW_PARAM_PERIOD_SIZE, val, dir);
+       unsigned int res;
+
+       if (snd_pcm_hw_param_set_near(pcm, params, SND_PCM_HW_PARAM_PERIOD_SIZE, val, dir, &res) < 0)
+               return 0;
+       return res;
 }
 
 /**
@@ -3389,7 +3464,11 @@ snd_pcm_uframes_t snd_pcm_hw_params_set_period_size_near(snd_pcm_t *pcm, snd_pcm
  */
 snd_pcm_uframes_t snd_pcm_hw_params_set_period_size_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir)
 {
-       return snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_PERIOD_SIZE, dir);
+       unsigned int res;
+
+       if (snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_PERIOD_SIZE, dir, &res) < 0)
+               return 0;
+       return res;
 }
 
 /**
@@ -3403,7 +3482,11 @@ snd_pcm_uframes_t snd_pcm_hw_params_set_period_size_first(snd_pcm_t *pcm, snd_pc
  */
 snd_pcm_uframes_t snd_pcm_hw_params_set_period_size_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir)
 {
-       return snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_PERIOD_SIZE, dir);
+       unsigned int res;
+
+       if (snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_PERIOD_SIZE, dir, &res) < 0)
+               return 0;
+       return res;
 }
 
 /**
@@ -3545,7 +3628,11 @@ int snd_pcm_hw_params_set_periods_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *pa
  */
 unsigned int snd_pcm_hw_params_set_periods_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int *dir)
 {
-       return snd_pcm_hw_param_set_near(pcm, params, SND_PCM_HW_PARAM_PERIODS, val, dir);
+       unsigned int res;
+
+       if (snd_pcm_hw_param_set_near(pcm, params, SND_PCM_HW_PARAM_PERIODS, val, dir, &res) < 0)
+               return 0;
+       return res;
 }
 
 /**
@@ -3559,7 +3646,11 @@ unsigned int snd_pcm_hw_params_set_periods_near(snd_pcm_t *pcm, snd_pcm_hw_param
  */
 unsigned int snd_pcm_hw_params_set_periods_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir)
 {
-       return snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_PERIODS, dir);
+       unsigned int res;
+
+       if (snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_PERIODS, dir, &res) < 0)
+               return 0;
+       return res;
 }
 
 /**
@@ -3573,7 +3664,11 @@ unsigned int snd_pcm_hw_params_set_periods_first(snd_pcm_t *pcm, snd_pcm_hw_para
  */
 unsigned int snd_pcm_hw_params_set_periods_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir)
 {
-       return snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_PERIODS, dir);
+       unsigned int res;
+
+       if (snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_PERIODS, dir, &res) < 0)
+               return 0;
+       return res;
 }
 
 /**
@@ -3715,7 +3810,11 @@ int snd_pcm_hw_params_set_buffer_time_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t
  */
 unsigned int snd_pcm_hw_params_set_buffer_time_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int *dir)
 {
-       return snd_pcm_hw_param_set_near(pcm, params, SND_PCM_HW_PARAM_BUFFER_TIME, val, dir);
+       unsigned int res;
+
+       if (snd_pcm_hw_param_set_near(pcm, params, SND_PCM_HW_PARAM_BUFFER_TIME, val, dir, &res) < 0)
+               return 0;
+       return res;
 }
 
 /**
@@ -3729,7 +3828,11 @@ unsigned int snd_pcm_hw_params_set_buffer_time_near(snd_pcm_t *pcm, snd_pcm_hw_p
  */
 unsigned int snd_pcm_hw_params_set_buffer_time_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir)
 {
-       return snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_BUFFER_TIME, dir);
+       unsigned int res;
+
+       if (snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_BUFFER_TIME, dir, &res) < 0)
+               return 0;
+       return res;
 }
 
 /**
@@ -3743,7 +3846,11 @@ unsigned int snd_pcm_hw_params_set_buffer_time_first(snd_pcm_t *pcm, snd_pcm_hw_
  */
 unsigned int snd_pcm_hw_params_set_buffer_time_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir)
 {
-       return snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_BUFFER_TIME, dir);
+       unsigned int res;
+       
+       if (snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_BUFFER_TIME, dir, &res) < 0)
+               return 0;
+       return res;
 }
 
 
@@ -3881,7 +3988,11 @@ int snd_pcm_hw_params_set_buffer_size_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t
  */
 snd_pcm_uframes_t snd_pcm_hw_params_set_buffer_size_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val)
 {
-       return snd_pcm_hw_param_set_near(pcm, params, SND_PCM_HW_PARAM_BUFFER_SIZE, val, NULL);
+       unsigned int res;
+
+       if (snd_pcm_hw_param_set_near(pcm, params, SND_PCM_HW_PARAM_BUFFER_SIZE, val, NULL, &res) < 0)
+               return 0;
+       return res;
 }
 
 /**
@@ -3892,7 +4003,11 @@ snd_pcm_uframes_t snd_pcm_hw_params_set_buffer_size_near(snd_pcm_t *pcm, snd_pcm
  */
 snd_pcm_uframes_t snd_pcm_hw_params_set_buffer_size_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
 {
-       return snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_BUFFER_SIZE, NULL);
+       unsigned int res;
+
+       if (snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_BUFFER_SIZE, NULL, &res) < 0)
+               return 0;
+       return res;
 }
 
 /**
@@ -3903,7 +4018,11 @@ snd_pcm_uframes_t snd_pcm_hw_params_set_buffer_size_first(snd_pcm_t *pcm, snd_pc
  */
 snd_pcm_uframes_t snd_pcm_hw_params_set_buffer_size_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
 {
-       return snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_BUFFER_SIZE, NULL);
+       unsigned int res;
+       
+       if (snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_BUFFER_SIZE, NULL, &res) < 0)
+               return 0;
+       return res;
 }
 
 
@@ -4034,7 +4153,11 @@ int snd_pcm_hw_params_set_tick_time_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *
  */
 unsigned int snd_pcm_hw_params_set_tick_time_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int *dir)
 {
-       return snd_pcm_hw_param_set_near(pcm, params, SND_PCM_HW_PARAM_TICK_TIME, val, dir);
+       unsigned int res;
+
+       if (snd_pcm_hw_param_set_near(pcm, params, SND_PCM_HW_PARAM_TICK_TIME, val, dir, &res) < 0)
+               return 0;
+       return res;
 }
 
 /**
@@ -4048,7 +4171,11 @@ unsigned int snd_pcm_hw_params_set_tick_time_near(snd_pcm_t *pcm, snd_pcm_hw_par
  */
 unsigned int snd_pcm_hw_params_set_tick_time_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir)
 {
-       return snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_TICK_TIME, dir);
+       unsigned int res;
+
+       if (snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_TICK_TIME, dir, &res) < 0)
+               return 0;
+       return res;
 }
 
 /**
@@ -4062,7 +4189,11 @@ unsigned int snd_pcm_hw_params_set_tick_time_first(snd_pcm_t *pcm, snd_pcm_hw_pa
  */
 unsigned int snd_pcm_hw_params_set_tick_time_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir)
 {
-       return snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_TICK_TIME, dir);
+       unsigned int res;
+
+       if (snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_TICK_TIME, dir, &res) < 0)
+               return 0;
+       return res;
 }
 
 /**
@@ -5163,7 +5294,10 @@ snd_pcm_sframes_t snd_pcm_write_areas(snd_pcm_t *pcm, const snd_pcm_channel_area
                if (state == SND_PCM_STATE_PREPARED) {
                        snd_pcm_sframes_t hw_avail = pcm->buffer_size - avail;
                        hw_avail += frames;
-                       if (hw_avail >= (snd_pcm_sframes_t) pcm->start_threshold) {
+                       /* some plugins might automatically start the stream */
+                       state = snd_pcm_state(pcm);
+                       if (state == SND_PCM_STATE_PREPARED &&
+                           hw_avail >= (snd_pcm_sframes_t) pcm->start_threshold) {
                                err = snd_pcm_start(pcm);
                                if (err < 0)
                                        goto _end;
index 23ae80e..3db0f1b 100644 (file)
@@ -473,6 +473,8 @@ void snd_pcm_hw_param_refine_near(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_empty(const snd_pcm_hw_params_t *params,
+                          snd_pcm_hw_param_t var);
 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);
@@ -489,13 +491,13 @@ int snd_pcm_hw_param_any(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
 int snd_pcm_hw_param_set_integer(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
                                 snd_set_mode_t mode,
                                 snd_pcm_hw_param_t var);
-unsigned int snd_pcm_hw_param_set_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
-                                       snd_pcm_hw_param_t var, int *dir);
-unsigned int snd_pcm_hw_param_set_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
-                                      snd_pcm_hw_param_t var, int *dir);
-unsigned int snd_pcm_hw_param_set_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
-                                      snd_pcm_hw_param_t var, unsigned int val,
-                                      int *dir);
+int snd_pcm_hw_param_set_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
+                              snd_pcm_hw_param_t var, int *dir, unsigned int *rval);
+int snd_pcm_hw_param_set_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
+                             snd_pcm_hw_param_t var, int *dir, unsigned int *rval);
+int snd_pcm_hw_param_set_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
+                             snd_pcm_hw_param_t var, unsigned int val,
+                             int *dir, unsigned int *rval);
 int snd_pcm_hw_param_set_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
                             snd_set_mode_t mode,
                             snd_pcm_hw_param_t var,
index 16b091b..0bf8760 100644 (file)
 
 static inline int hw_is_mask(snd_pcm_hw_param_t var)
 {
+#if SND_PCM_HW_PARAM_FIRST_MASK == 0
+       return var <= SND_PCM_HW_PARAM_LAST_MASK;
+#else
        return var >= SND_PCM_HW_PARAM_FIRST_MASK &&
                var <= SND_PCM_HW_PARAM_LAST_MASK;
+#endif
 }
 
 static inline int hw_is_interval(snd_pcm_hw_param_t var)
@@ -285,16 +289,26 @@ static int _snd_pcm_hw_param_set_first(snd_pcm_hw_params_t *params,
    values > minimum. Reduce configuration space accordingly.
    Return the minimum.
 */
-unsigned int snd_pcm_hw_param_set_first(snd_pcm_t *pcm, 
-                                       snd_pcm_hw_params_t *params, 
-                                       snd_pcm_hw_param_t var, int *dir)
+int snd_pcm_hw_param_set_first(snd_pcm_t *pcm, 
+                              snd_pcm_hw_params_t *params, 
+                              snd_pcm_hw_param_t var,
+                              int *dir, unsigned int *rval)
 {
-       _snd_pcm_hw_param_set_first(params, var);
+       int err;
+       unsigned int val;
+
+       err = _snd_pcm_hw_param_set_first(params, var);
+       if (err < 0)
+               return err;
        if (params->rmask) {
-               int err = snd_pcm_hw_refine(pcm, params);
-               assert(err >= 0);
+               err = snd_pcm_hw_refine(pcm, params);
+               if (err < 0)
+                       return err;
        }
-       return snd_pcm_hw_param_get(params, var, dir);
+       val = snd_pcm_hw_param_get(params, var, dir);
+       if (rval)
+               *rval = val;
+       return 0;
 }
 
 static int _snd_pcm_hw_param_set_last(snd_pcm_hw_params_t *params,
@@ -321,16 +335,26 @@ static int _snd_pcm_hw_param_set_last(snd_pcm_hw_params_t *params,
    values < maximum. Reduce configuration space accordingly.
    Return the maximum.
 */
-unsigned int snd_pcm_hw_param_set_last(snd_pcm_t *pcm, 
-                                      snd_pcm_hw_params_t *params,
-                                      snd_pcm_hw_param_t var, int *dir)
+int snd_pcm_hw_param_set_last(snd_pcm_t *pcm, 
+                             snd_pcm_hw_params_t *params,
+                             snd_pcm_hw_param_t var,
+                             int *dir, unsigned int *rval)
 {
-       _snd_pcm_hw_param_set_last(params, var);
+       int err;
+       unsigned int val;
+
+       err = _snd_pcm_hw_param_set_last(params, var);
+       if (err < 0)
+               return err;
        if (params->rmask) {
-               int err = snd_pcm_hw_refine(pcm, params);
-               assert(err >= 0);
+               err = snd_pcm_hw_refine(pcm, params);
+               if (err < 0)
+                       return err;
        }
-       return snd_pcm_hw_param_get(params, var, dir);
+       val = snd_pcm_hw_param_get(params, var, dir);
+       if (rval)
+               *rval = val;
+       return 0;
 }
 
 int _snd_pcm_hw_param_set_min(snd_pcm_hw_params_t *params,
@@ -503,7 +527,7 @@ int _snd_pcm_hw_param_set_minmax(snd_pcm_hw_params_t *params,
        if (hw_is_mask(var)) {
                snd_mask_t *mask = hw_param_mask(params, var);
                if (max == 0 && openmax) {
-               snd_mask_none(mask);
+                       snd_mask_none(mask);
                        changed = -EINVAL;
                } else {
                        c1 = snd_mask_refine_min(mask, min + !!openmin);
@@ -735,11 +759,12 @@ int snd_pcm_hw_param_set_mask(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
    SND_PCM_HW_PARAM_FORMAT, SND_PCM_HW_PARAM_SUBFORMAT.
    Return the value found.
  */
-unsigned int snd_pcm_hw_param_set_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
-                                      snd_pcm_hw_param_t var, unsigned int best, int *dir)
+int snd_pcm_hw_param_set_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
+                             snd_pcm_hw_param_t var, unsigned int best,
+                             int *dir, unsigned int *val)
 {
        snd_pcm_hw_params_t save;
-       int v, err;
+       int err;
        unsigned int saved_min;
        int last = 0;
        int min, max;
@@ -778,16 +803,16 @@ unsigned int snd_pcm_hw_param_set_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *para
        } else {
                *params = save;
                err = snd_pcm_hw_param_set_max(pcm, params, SND_CHANGE, var, &max, &maxdir);
-               assert(err >= 0);
+               if (err < 0)
+                       return err;
                last = 1;
        }
  _end:
        if (last)
-               v = snd_pcm_hw_param_set_last(pcm, params, var, dir);
+               err = snd_pcm_hw_param_set_last(pcm, params, var, dir, val);
        else
-               v = snd_pcm_hw_param_set_first(pcm, params, var, dir);
-       assert(v >= 0);
-       return v;
+               err = snd_pcm_hw_param_set_first(pcm, params, var, dir, val);
+       return err;
 }
 
 #if 0
@@ -863,23 +888,23 @@ int snd_pcm_hw_param_set_next(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
 }
 #endif
 
-static void snd_pcm_hw_param_set_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)
+static int snd_pcm_hw_param_set_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 (!boundary_lt(min, *mindir, max, *maxdir)) {
-               snd_pcm_hw_param_set_near(pcm, params, var, min, mindir);
-               return;
-       }
+       if (!boundary_lt(min, *mindir, max, *maxdir))
+               return snd_pcm_hw_param_set_near(pcm, params, var, min, mindir, NULL);
        tmp = *params;
-       min = snd_pcm_hw_param_set_near(pcm, &tmp, var, min, mindir);
+       err = snd_pcm_hw_param_set_near(pcm, &tmp, var, min, mindir, &min);
+       if (err < 0)
+               return err;
        if (boundary_lt(min, *mindir, max, *maxdir)) {
                tmp = *params;
-               max = snd_pcm_hw_param_set_near(pcm, &tmp, var, max, maxdir);
+               err = snd_pcm_hw_param_set_near(pcm, &tmp, var, max, maxdir, &max);
        } else {
                max = min;
                *maxdir = *mindir;
@@ -887,6 +912,7 @@ static void snd_pcm_hw_param_set_near_minmax(snd_pcm_t *pcm,
        err = snd_pcm_hw_param_set_minmax(pcm, params, SND_CHANGE, var, &min, mindir,
                                          &max, maxdir);
        assert(err >= 0);
+       return 0;
 }
 
 void snd_pcm_hw_param_refine_near(snd_pcm_t *pcm,
@@ -904,9 +930,8 @@ void snd_pcm_hw_param_refine_near(snd_pcm_t *pcm,
 
 /* ---- end of refinement functions ---- */
 
-#if 0
-static int snd_pcm_hw_param_empty(const snd_pcm_hw_params_t *params,
-                                 snd_pcm_hw_param_t var)
+int snd_pcm_hw_param_empty(const snd_pcm_hw_params_t *params,
+                          snd_pcm_hw_param_t var)
 {
        if (hw_is_mask(var))
                return snd_mask_empty(hw_param_mask_c(params, var));
@@ -915,7 +940,6 @@ static int snd_pcm_hw_param_empty(const snd_pcm_hw_params_t *params,
        assert(0);
        return -EINVAL;
 }
-#endif
 
 int snd_pcm_hw_param_always_eq(const snd_pcm_hw_params_t *params,
                               snd_pcm_hw_param_t var,
@@ -957,17 +981,38 @@ int snd_pcm_hw_param_never_eq(const snd_pcm_hw_params_t *params,
    max buffer size
    min tick time
 */
-static void snd_pcm_hw_params_choose(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
+static int snd_pcm_hw_params_choose(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
 {
-       snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_ACCESS, 0);
-       snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_FORMAT, 0);
-       snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_SUBFORMAT, 0);
-       snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_CHANNELS, 0);
-       snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_RATE, 0);
-       snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_PERIOD_TIME, 0);
-       snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_PERIOD_SIZE, 0);
-       snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_BUFFER_SIZE, 0);
-       snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_TICK_TIME, 0);
+       int err;
+
+       err = snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_ACCESS, 0, NULL);
+       if (err < 0)
+               return err;
+       snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_FORMAT, 0, NULL);
+       if (err < 0)
+               return err;
+       snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_SUBFORMAT, 0, NULL);
+       if (err < 0)
+               return err;
+       snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_CHANNELS, 0, NULL);
+       if (err < 0)
+               return err;
+       snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_RATE, 0, NULL);
+       if (err < 0)
+               return err;
+       snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_PERIOD_TIME, 0, NULL);
+       if (err < 0)
+               return err;
+       snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_PERIOD_SIZE, 0, NULL);
+       if (err < 0)
+               return err;
+       snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_BUFFER_SIZE, 0, NULL);
+       if (err < 0)
+               return err;
+       snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_TICK_TIME, 0, NULL);
+       if (err < 0)
+               return err;
+       return 0;
 }
 
 #if 0
@@ -1989,13 +2034,20 @@ int snd_pcm_hw_refine_slave(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
                if (err >= 0) {
 #ifdef RULES_DEBUG
                        snd_output_printf(log, "srefine '%s'\n", pcm->name);
-                       snd_pcm_hw_params_dump(params, log);
+                       snd_pcm_hw_params_dump(&sparams, log);
 #endif
                        err = srefine(pcm, &sparams);
-               }
-               if (err < 0) {
+                       if (err < 0) {
+#ifdef RULES_DEBUG
+                               snd_output_printf(log, "srefine '%s', err < 0 (%i)\n", pcm->name, err);
+                               snd_pcm_hw_params_dump(&sparams, log);
+#endif
+                               cchange(pcm, params, &sparams);
+                               return err;
+                       }
+               } else {
 #ifdef RULES_DEBUG
-                       snd_output_printf(log, "cchange '%s', (schange || srefine) < 0\n", pcm->name);
+                       snd_output_printf(log, "schange '%s', err < 0 (%i)\n", pcm->name, err);
                        snd_pcm_hw_params_dump(params, log);
 #endif
                        cchange(pcm, params, &sparams);
index 656c742..2abe79a 100644 (file)
@@ -530,12 +530,18 @@ static int snd_pcm_plug_hw_refine_cprepare(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_
 
        /* HACK: to avoid overflow in PARTBIT_RATE code */
        rate_min = snd_pcm_hw_param_get_min(params, SND_PCM_HW_PARAM_RATE, NULL);
-       if (rate_min < 4000)
+       if (rate_min < 4000) {
                _snd_pcm_hw_param_set_min(params, SND_PCM_HW_PARAM_RATE, 4000, 0);
+               if (snd_pcm_hw_param_empty(params, SND_PCM_HW_PARAM_RATE))
+                       return -EINVAL;
+       }
        /* HACK: to avoid overflow in PERIOD_SIZE code */
        channels_max = snd_pcm_hw_param_get_max(params, SND_PCM_HW_PARAM_CHANNELS, NULL);
-       if (channels_max > 10000)
+       if (channels_max > 10000) {
                _snd_pcm_hw_param_set_max(params, SND_PCM_HW_PARAM_CHANNELS, 10000, 0);
+               if (snd_pcm_hw_param_empty(params, SND_PCM_HW_PARAM_CHANNELS))
+                       return -EINVAL;
+       }
        return 0;
 }
 
@@ -574,6 +580,7 @@ static int snd_pcm_plug_hw_refine_schange(snd_pcm_t *pcm, snd_pcm_hw_params_t *p
        snd_pcm_format_t format;
        snd_interval_t t, buffer_size;
        const snd_interval_t *srate, *crate;
+
        if (plug->srate == -2)
                links |= SND_PCM_HW_PARBIT_RATE;
        else {
@@ -609,7 +616,7 @@ static int snd_pcm_plug_hw_refine_schange(snd_pcm_t *pcm, snd_pcm_hw_params_t *p
                }
 
                if (snd_pcm_format_mask_empty(&sfmt_mask)) {
-                       SNDERR("Unable to find an useable slave format");
+                       SNDERR("Unable to find an useable slave format for '%s'", pcm->name);
                        for (format = 0; format <= SND_PCM_FORMAT_LAST; format++) {
                                if (!snd_pcm_format_mask_test(format_mask, format))
                                        continue;
@@ -624,7 +631,8 @@ static int snd_pcm_plug_hw_refine_schange(snd_pcm_t *pcm, snd_pcm_hw_params_t *p
                }
                err = snd_pcm_hw_param_set_mask(slave, sparams, SND_CHANGE,
                                                SND_PCM_HW_PARAM_FORMAT, &sfmt_mask);
-               assert(err >= 0);
+               if (err < 0)
+                       return -EINVAL;
        }
 
        if (snd_pcm_hw_param_never_eq(params, SND_PCM_HW_PARAM_FORMAT, sparams) ||
@@ -634,6 +642,10 @@ static int snd_pcm_plug_hw_refine_schange(snd_pcm_t *pcm, snd_pcm_hw_params_t *p
                snd_pcm_access_mask_t access_mask = { SND_PCM_ACCBIT_MMAP };
                _snd_pcm_hw_param_set_mask(sparams, SND_PCM_HW_PARAM_ACCESS,
                                           &access_mask);
+               if (snd_pcm_access_mask_empty(snd_pcm_hw_param_get_mask(sparams, SND_PCM_HW_PARAM_ACCESS))) {
+                       SNDERR("Unable to find an useable access for '%s'", pcm->name);
+                       return -EINVAL;
+               }
        }
        if ((links & SND_PCM_HW_PARBIT_RATE) ||
            snd_pcm_hw_param_always_eq(params, SND_PCM_HW_PARAM_RATE, sparams))