]> git.alsa-project.org Git - alsa-lib.git/commitdiff
Runtime hw_info constraints support. New hw_info with lengths
authorAbramo Bagnara <abramo@alsa-project.org>
Thu, 7 Dec 2000 15:58:03 +0000 (15:58 +0000)
committerAbramo Bagnara <abramo@alsa-project.org>
Thu, 7 Dec 2000 15:58:03 +0000 (15:58 +0000)
include/pcm.h
src/pcm/pcm.c
src/pcm/pcm_local.h
src/pcm/pcm_multi.c
src/pcm/pcm_plug.c
src/pcm/pcm_plugin.h
src/pcm/pcm_rate.c

index b85d5243434c0f440ffa5fb9739b39e04afec5ab..c1dfd3c4c8b732db2da2be0d1cb5c1da5a47d234 100644 (file)
@@ -109,7 +109,7 @@ typedef struct _snd_pcm_strategy snd_pcm_strategy_t;
 
 /* choices need to be sorted on ascending badness */
 typedef struct _snd_pcm_strategy_simple_choices_list {
-       unsigned long value;
+       unsigned int value;
        unsigned int badness;
 } snd_pcm_strategy_simple_choices_list_t;
 
@@ -122,7 +122,7 @@ int snd_pcm_strategy_simple(snd_pcm_strategy_t **strategyp,
                            unsigned int badness_max);
 int snd_pcm_strategy_simple_near(snd_pcm_strategy_t *strategy, int order,
                                 unsigned int param,
-                                unsigned long best,
+                                unsigned int best,
                                 unsigned int mul);
 int snd_pcm_strategy_simple_choices(snd_pcm_strategy_t *strategy, int order,
                                    unsigned int param,
index 5eaa2d405194ebe308d5717d5939ac26eab80fb5..0ebe3f9af2e27050224ce465032cfdaba7db01a2 100644 (file)
@@ -122,12 +122,12 @@ void snd_pcm_hw_info_any(snd_pcm_hw_info_t *info)
        info->channels_max = UINT_MAX;
        info->rate_min = 1;
        info->rate_max = UINT_MAX;
-       info->fragment_size_min = 1;
-       info->fragment_size_max = ULONG_MAX;
+       info->fragment_length_min = 0;
+       info->fragment_length_max = UINT_MAX;
        info->fragments_min = 1;
        info->fragments_max = UINT_MAX;
-       info->buffer_size_min = 1;
-       info->buffer_size_max = ULONG_MAX;
+       info->buffer_length_min = 1;
+       info->buffer_length_max = UINT_MAX;
 }
 
 void snd_pcm_hw_params_to_info(snd_pcm_hw_params_t *params, snd_pcm_hw_info_t *info)
@@ -138,9 +138,9 @@ void snd_pcm_hw_params_to_info(snd_pcm_hw_params_t *params, snd_pcm_hw_info_t *i
        info->subformat_mask = 1U << params->subformat;
        info->channels_min = info->channels_max = params->channels;
        info->rate_min = info->rate_max = params->rate;
-       info->fragment_size_min = info->fragment_size_max = params->fragment_size;
+       info->fragment_length_min = info->fragment_length_max = muldiv_down(params->fragment_size, 1000000, params->rate);
        info->fragments_min = info->fragments_max = params->fragments;
-       info->buffer_size_min = info->buffer_size_max = params->fragment_size * params->fragments;
+       info->buffer_length_min = info->buffer_length_max = muldiv_down(params->fragment_size * params->fragments, 1000000, params->rate);
 }
 
 int snd_pcm_hw_info_to_params(snd_pcm_t *pcm, snd_pcm_hw_info_t *info, snd_pcm_hw_params_t *params)
@@ -182,9 +182,9 @@ int snd_pcm_hw_info_to_params(snd_pcm_t *pcm, snd_pcm_hw_info_t *info, snd_pcm_h
                err = snd_pcm_hw_info(pcm, info);
                assert(err >= 0);
        }
-       assert(i.fragment_size_min <= i.fragment_size_max);
-       if (i.fragment_size_min < i.fragment_size_max) {
-               i.fragment_size_max = i.fragment_size_min;
+       assert(i.fragment_length_min <= i.fragment_length_max);
+       if (i.fragment_length_min < i.fragment_length_max) {
+               i.fragment_length_max = i.fragment_length_min;
                err = snd_pcm_hw_info(pcm, info);
                assert(err >= 0);
        }
@@ -199,7 +199,7 @@ int snd_pcm_hw_info_to_params(snd_pcm_t *pcm, snd_pcm_hw_info_t *info, snd_pcm_h
        params->subformat = ffs(i.subformat_mask) - 1;
        params->channels = i.channels_min;
        params->rate = i.rate_min;
-       params->fragment_size = i.fragment_size_min;
+       params->fragment_size = muldiv_near(i.fragment_length_min, i.rate_min, 1000000);
        params->fragments = i.fragments_min;
        return 0;
 }
@@ -429,6 +429,7 @@ int snd_pcm_poll_descriptor(snd_pcm_t *pcm)
 #define XRUN(v) [SND_PCM_XRUN_##v] = #v
 #define ACCESS(v) [SND_PCM_ACCESS_##v] = #v
 #define START(v) [SND_PCM_START_##v] = #v
+#define HW_INFO(v) [SND_PCM_HW_INFO_##v] = #v
 #define HW_PARAM(v) [SND_PCM_HW_PARAM_##v] = #v
 #define SW_PARAM(v) [SND_PCM_SW_PARAM_##v] = #v
 #define FORMAT(v) [SND_PCM_FORMAT_##v] = #v
@@ -451,6 +452,17 @@ char *snd_pcm_state_names[] = {
        STATE(PAUSED),
 };
 
+char *snd_pcm_hw_info_names[] = {
+       HW_INFO(ACCESS),
+       HW_INFO(FORMAT),
+       HW_INFO(SUBFORMAT),
+       HW_INFO(CHANNELS),
+       HW_INFO(RATE),
+       HW_INFO(FRAGMENT_LENGTH),
+       HW_INFO(FRAGMENTS),
+       HW_INFO(BUFFER_LENGTH),
+};
+
 char *snd_pcm_hw_param_names[] = {
        HW_PARAM(ACCESS),
        HW_PARAM(FORMAT),
@@ -459,7 +471,6 @@ char *snd_pcm_hw_param_names[] = {
        HW_PARAM(RATE),
        HW_PARAM(FRAGMENT_SIZE),
        HW_PARAM(FRAGMENTS),
-       HW_PARAM(BUFFER_SIZE),
 };
 
 char *snd_pcm_sw_param_names[] = {
@@ -1448,9 +1459,9 @@ struct _snd_pcm_strategy {
        int (*choose_param)(const snd_pcm_hw_info_t *info,
                            snd_pcm_t *pcm,
                            const snd_pcm_strategy_t *strategy);
-       long (*next_value)(const snd_pcm_hw_info_t *info,
+       int (*next_value)(const snd_pcm_hw_info_t *info,
                           unsigned int param,
-                          long value,
+                          int value,
                           snd_pcm_t *pcm,
                           const snd_pcm_strategy_t *strategy);
        int (*min_badness)(const snd_pcm_hw_info_t *info,
@@ -1467,9 +1478,9 @@ typedef struct _snd_pcm_strategy_simple snd_pcm_strategy_simple_t;
 struct _snd_pcm_strategy_simple {
        int valid;
        unsigned int order;
-       long (*next_value)(const snd_pcm_hw_info_t *info,
+       int (*next_value)(const snd_pcm_hw_info_t *info,
                           unsigned int param,
-                          long value,
+                          int value,
                           snd_pcm_t *pcm,
                           const snd_pcm_strategy_simple_t *par);
        unsigned int (*min_badness)(const snd_pcm_hw_info_t *info,
@@ -1481,7 +1492,7 @@ struct _snd_pcm_strategy_simple {
 };
 
 typedef struct _snd_pcm_strategy_simple_near {
-       long best;
+       int best;
        unsigned int mul;
 } snd_pcm_strategy_simple_near_t;
 
@@ -1531,43 +1542,43 @@ typedef struct {
        unsigned int last;
 } par_desc_t;
 
-par_desc_t hw_pars[SND_PCM_HW_PARAM_LAST + 1] = {
-       [SND_PCM_HW_PARAM_ACCESS] = {
+par_desc_t hw_infos[SND_PCM_HW_INFO_LAST + 1] = {
+       [SND_PCM_HW_INFO_ACCESS] = {
                type: MASK,
                names: snd_pcm_access_names,
                last: SND_PCM_ACCESS_LAST,
        },
-       [SND_PCM_HW_PARAM_FORMAT] = {
+       [SND_PCM_HW_INFO_FORMAT] = {
                type: MASK,
                names: snd_pcm_format_names,
                last: SND_PCM_FORMAT_LAST,
        },
-       [SND_PCM_HW_PARAM_SUBFORMAT] = {
+       [SND_PCM_HW_INFO_SUBFORMAT] = {
                type: MASK,
                names: snd_pcm_subformat_names,
                last: SND_PCM_SUBFORMAT_LAST,
        },
-       [SND_PCM_HW_PARAM_CHANNELS] = {
+       [SND_PCM_HW_INFO_CHANNELS] = {
                type: MINMAX,
                names: 0,
                last: 0,
        },
-       [SND_PCM_HW_PARAM_RATE] = {
+       [SND_PCM_HW_INFO_RATE] = {
                type: MINMAX,
                names: 0,
                last: 0,
        },
-       [SND_PCM_HW_PARAM_FRAGMENT_SIZE] = {
+       [SND_PCM_HW_INFO_FRAGMENT_LENGTH] = {
                type: MINMAX,
                names: 0,
                last: 0,
        },
-       [SND_PCM_HW_PARAM_FRAGMENTS] = {
+       [SND_PCM_HW_INFO_FRAGMENTS] = {
                type: MINMAX,
                names: 0,
                last: 0,
        },
-       [SND_PCM_HW_PARAM_BUFFER_SIZE] = {
+       [SND_PCM_HW_INFO_BUFFER_LENGTH] = {
                type: MINMAX,
                names: 0,
                last: 0,
@@ -1578,11 +1589,11 @@ unsigned int snd_pcm_hw_info_par_get_mask(const snd_pcm_hw_info_t *info,
                                          unsigned int param)
 {
        switch (param) {
-       case SND_PCM_HW_PARAM_ACCESS:
+       case SND_PCM_HW_INFO_ACCESS:
                return info->access_mask;
-       case SND_PCM_HW_PARAM_FORMAT:
+       case SND_PCM_HW_INFO_FORMAT:
                return info->format_mask;
-       case SND_PCM_HW_PARAM_SUBFORMAT:
+       case SND_PCM_HW_INFO_SUBFORMAT:
                return info->subformat_mask;
        default:
                assert(0);
@@ -1592,12 +1603,12 @@ unsigned int snd_pcm_hw_info_par_get_mask(const snd_pcm_hw_info_t *info,
        
 void snd_pcm_hw_info_par_get_minmax(const snd_pcm_hw_info_t *info,
                                    unsigned int param,
-                                   unsigned long *min, unsigned long *max)
+                                   unsigned int *min, unsigned int *max)
 {
        switch (param) {
-       case SND_PCM_HW_PARAM_ACCESS:
-       case SND_PCM_HW_PARAM_FORMAT:
-       case SND_PCM_HW_PARAM_SUBFORMAT:
+       case SND_PCM_HW_INFO_ACCESS:
+       case SND_PCM_HW_INFO_FORMAT:
+       case SND_PCM_HW_INFO_SUBFORMAT:
        {
                unsigned int mask = snd_pcm_hw_info_par_get_mask(info, param);
                if (!mask) {
@@ -1609,25 +1620,25 @@ void snd_pcm_hw_info_par_get_minmax(const snd_pcm_hw_info_t *info,
                }
                break;
        }
-       case SND_PCM_HW_PARAM_CHANNELS:
+       case SND_PCM_HW_INFO_CHANNELS:
                *min = info->channels_min;
                *max = info->channels_max;
                break;
-       case SND_PCM_HW_PARAM_RATE:
+       case SND_PCM_HW_INFO_RATE:
                *min = info->rate_min;
                *max = info->rate_max;
                break;
-       case SND_PCM_HW_PARAM_FRAGMENT_SIZE:
-               *min = info->fragment_size_min;
-               *max = info->fragment_size_max;
+       case SND_PCM_HW_INFO_FRAGMENT_LENGTH:
+               *min = info->fragment_length_min;
+               *max = info->fragment_length_max;
                break;
-       case SND_PCM_HW_PARAM_FRAGMENTS:
+       case SND_PCM_HW_INFO_FRAGMENTS:
                *min = info->fragments_min;
                *max = info->fragments_max;
                break;
-       case SND_PCM_HW_PARAM_BUFFER_SIZE:
-               *min = info->buffer_size_min;
-               *max = info->buffer_size_max;
+       case SND_PCM_HW_INFO_BUFFER_LENGTH:
+               *min = info->buffer_length_min;
+               *max = info->buffer_length_max;
                break;
        default:
                assert(0);
@@ -1638,13 +1649,13 @@ void snd_pcm_hw_info_par_set_mask(snd_pcm_hw_info_t *info, unsigned int param,
                                  unsigned int v)
 {
        switch (param) {
-       case SND_PCM_HW_PARAM_ACCESS:
+       case SND_PCM_HW_INFO_ACCESS:
                info->access_mask = v;
                break;
-       case SND_PCM_HW_PARAM_FORMAT:
+       case SND_PCM_HW_INFO_FORMAT:
                info->format_mask = v;
                break;
-       case SND_PCM_HW_PARAM_SUBFORMAT:
+       case SND_PCM_HW_INFO_SUBFORMAT:
                info->subformat_mask = v;
                break;
        default:
@@ -1654,12 +1665,12 @@ void snd_pcm_hw_info_par_set_mask(snd_pcm_hw_info_t *info, unsigned int param,
 
 void snd_pcm_hw_info_par_set_minmax(snd_pcm_hw_info_t *info,
                                    unsigned int param,
-                                   unsigned long min, unsigned long max)
+                                   unsigned int min, unsigned int max)
 {
        switch (param) {
-       case SND_PCM_HW_PARAM_ACCESS:
-       case SND_PCM_HW_PARAM_FORMAT:
-       case SND_PCM_HW_PARAM_SUBFORMAT:
+       case SND_PCM_HW_INFO_ACCESS:
+       case SND_PCM_HW_INFO_FORMAT:
+       case SND_PCM_HW_INFO_SUBFORMAT:
        {
                unsigned int mask;
                if (min >= 32 || max <= 0 || min > max) {
@@ -1676,25 +1687,25 @@ void snd_pcm_hw_info_par_set_minmax(snd_pcm_hw_info_t *info,
                snd_pcm_hw_info_par_set_mask(info, param, mask);
                break;
        }
-       case SND_PCM_HW_PARAM_CHANNELS:
+       case SND_PCM_HW_INFO_CHANNELS:
                info->channels_min = min;
                info->channels_max = max;
                break;
-       case SND_PCM_HW_PARAM_RATE:
+       case SND_PCM_HW_INFO_RATE:
                info->rate_min = min;
                info->rate_max = max;
                break;
-       case SND_PCM_HW_PARAM_FRAGMENT_SIZE:
-               info->fragment_size_min = min;
-               info->fragment_size_max = max;
+       case SND_PCM_HW_INFO_FRAGMENT_LENGTH:
+               info->fragment_length_min = min;
+               info->fragment_length_max = max;
                break;
-       case SND_PCM_HW_PARAM_FRAGMENTS:
+       case SND_PCM_HW_INFO_FRAGMENTS:
                info->fragments_min = min;
                info->fragments_max = max;
                break;
-       case SND_PCM_HW_PARAM_BUFFER_SIZE:
-               info->buffer_size_min = min;
-               info->buffer_size_max = max;
+       case SND_PCM_HW_INFO_BUFFER_LENGTH:
+               info->buffer_length_min = min;
+               info->buffer_length_max = max;
                break;
        default:
                assert(0);
@@ -1705,34 +1716,34 @@ void snd_pcm_hw_info_par_copy(snd_pcm_hw_info_t *info, unsigned int param,
                              snd_pcm_hw_info_t *src)
 {
        switch (param) {
-       case SND_PCM_HW_PARAM_ACCESS:
+       case SND_PCM_HW_INFO_ACCESS:
                info->access_mask = src->access_mask;
                break;
-       case SND_PCM_HW_PARAM_FORMAT:
+       case SND_PCM_HW_INFO_FORMAT:
                info->format_mask = src->format_mask;
                break;
-       case SND_PCM_HW_PARAM_SUBFORMAT:
+       case SND_PCM_HW_INFO_SUBFORMAT:
                info->subformat_mask = src->subformat_mask;
                break;
-       case SND_PCM_HW_PARAM_CHANNELS:
+       case SND_PCM_HW_INFO_CHANNELS:
                info->channels_min = src->channels_min;
                info->channels_max = src->channels_max;
                break;
-       case SND_PCM_HW_PARAM_RATE:
+       case SND_PCM_HW_INFO_RATE:
                info->rate_min = src->rate_min;
                info->rate_max = src->rate_max;
                break;
-       case SND_PCM_HW_PARAM_FRAGMENT_SIZE:
-               info->fragment_size_min = src->fragment_size_min;
-               info->fragment_size_max = src->fragment_size_max;
+       case SND_PCM_HW_INFO_FRAGMENT_LENGTH:
+               info->fragment_length_min = src->fragment_length_min;
+               info->fragment_length_max = src->fragment_length_max;
                break;
-       case SND_PCM_HW_PARAM_FRAGMENTS:
+       case SND_PCM_HW_INFO_FRAGMENTS:
                info->fragments_min = src->fragments_min;
                info->fragments_max = src->fragments_max;
                break;
-       case SND_PCM_HW_PARAM_BUFFER_SIZE:
-               info->buffer_size_min = src->buffer_size_min;
-               info->buffer_size_max = src->buffer_size_max;
+       case SND_PCM_HW_INFO_BUFFER_LENGTH:
+               info->buffer_length_min = src->buffer_length_min;
+               info->buffer_length_max = src->buffer_length_max;
                break;
        default:
                assert(0);
@@ -1740,18 +1751,18 @@ void snd_pcm_hw_info_par_copy(snd_pcm_hw_info_t *info, unsigned int param,
        }
 }
 
-unsigned long snd_pcm_hw_info_par_choices(const snd_pcm_hw_info_t *info,
+unsigned int snd_pcm_hw_info_par_choices(const snd_pcm_hw_info_t *info,
                                          unsigned int param)
 {
        par_desc_t *p;
-       assert(param <= SND_PCM_HW_PARAM_LAST);
-       p = &hw_pars[param];
+       assert(param <= SND_PCM_HW_INFO_LAST);
+       p = &hw_infos[param];
        switch (p->type) {
        case MASK:
                return hweight32(snd_pcm_hw_info_par_get_mask(info, param));
        case MINMAX:
        {
-               unsigned long min, max;
+               unsigned int min, max;
                snd_pcm_hw_info_par_get_minmax(info, param, &min, &max);
                return max - min + 1;
        }
@@ -1761,11 +1772,11 @@ unsigned long snd_pcm_hw_info_par_choices(const snd_pcm_hw_info_t *info,
        }
 }
 
-unsigned long snd_pcm_hw_info_par_refine_min(snd_pcm_hw_info_t *info,
+unsigned int snd_pcm_hw_info_par_refine_min(snd_pcm_hw_info_t *info,
                                             unsigned int param,
-                                            unsigned long value)
+                                            unsigned int value)
 {
-       unsigned long min, max;
+       unsigned int min, max;
        snd_pcm_hw_info_par_get_minmax(info, param, &min, &max);
        if (min < value) {
                min = value;
@@ -1774,11 +1785,11 @@ unsigned long snd_pcm_hw_info_par_refine_min(snd_pcm_hw_info_t *info,
        return min;
 }
 
-unsigned long snd_pcm_hw_info_par_refine_max(snd_pcm_hw_info_t *info,
+unsigned int snd_pcm_hw_info_par_refine_max(snd_pcm_hw_info_t *info,
                                             unsigned int param,
-                                            unsigned long value)
+                                            unsigned int value)
 {
-       unsigned long min, max;
+       unsigned int min, max;
        snd_pcm_hw_info_par_get_minmax(info, param, &min, &max);
        if (max > value) {
                max = value;
@@ -1789,17 +1800,17 @@ unsigned long snd_pcm_hw_info_par_refine_max(snd_pcm_hw_info_t *info,
 
 int snd_pcm_hw_info_par_check(const snd_pcm_hw_info_t *info, 
                              unsigned int param,
-                             unsigned long value)
+                             unsigned int value)
 {
        par_desc_t *p;
-       assert(param <= SND_PCM_HW_PARAM_LAST);
-       p = &hw_pars[param];
+       assert(param <= SND_PCM_HW_INFO_LAST);
+       p = &hw_infos[param];
        switch (p->type) {
        case MASK:
                return snd_pcm_hw_info_par_get_mask(info, param) & (1 << value);
        case MINMAX:
        {
-               unsigned long min, max;
+               unsigned int min, max;
                snd_pcm_hw_info_par_get_minmax(info, param, &min, &max);
                return value >= min && value <= max;
        }
@@ -1809,13 +1820,13 @@ int snd_pcm_hw_info_par_check(const snd_pcm_hw_info_t *info,
        }
 }
 
-long snd_pcm_hw_info_par_nearest_next(const snd_pcm_hw_info_t *info,
+int snd_pcm_hw_info_par_nearest_next(const snd_pcm_hw_info_t *info,
                                      unsigned int param,
-                                     unsigned long best, long value,
+                                     unsigned int best, int value,
                                      snd_pcm_t *pcm)
 {
-       unsigned long min, max;
-       unsigned long max1, min2;
+       unsigned int min, max;
+       unsigned int max1, min2;
        snd_pcm_hw_info_t i1, i2;
        int err1 = -EINVAL;
        int err2 = -EINVAL;
@@ -1827,7 +1838,7 @@ long snd_pcm_hw_info_par_nearest_next(const snd_pcm_hw_info_t *info,
                max1 = best;
                min2 = best + 1;
        } else {
-               long diff = value - best;
+               int diff = value - best;
                if (diff < 0) {
                        if (value > 1)
                                max1 = value - 1;
@@ -1835,7 +1846,7 @@ long snd_pcm_hw_info_par_nearest_next(const snd_pcm_hw_info_t *info,
                                max1 = 0;
                        min2 = best - diff;
                } else {
-                       if (best > (unsigned long) diff)
+                       if (best > (unsigned int) diff)
                                max1 = best - diff - 1;
                        else
                                max1 = 0;
@@ -1868,8 +1879,8 @@ long snd_pcm_hw_info_par_nearest_next(const snd_pcm_hw_info_t *info,
 void snd_pcm_hw_info_par_dump(snd_pcm_hw_info_t *info, unsigned int param, FILE *fp)
 {
        par_desc_t *p;
-       assert(param <= SND_PCM_HW_PARAM_LAST);
-       p = &hw_pars[param];
+       assert(param <= SND_PCM_HW_INFO_LAST);
+       p = &hw_infos[param];
        switch (p->type) {
        case MASK:
        {
@@ -1889,9 +1900,9 @@ void snd_pcm_hw_info_par_dump(snd_pcm_hw_info_t *info, unsigned int param, FILE
        }
        case MINMAX:
        {
-               unsigned long min, max;
+               unsigned int min, max;
                snd_pcm_hw_info_par_get_minmax(info, param, &min, &max);
-               printf("%ld - %ld", min, max);
+               printf("%d - %d", min, max);
                break;
        }
        default:
@@ -1903,14 +1914,14 @@ void snd_pcm_hw_info_par_dump(snd_pcm_hw_info_t *info, unsigned int param, FILE
 int snd_pcm_hw_info_par_empty(snd_pcm_hw_info_t *info, unsigned int param)
 {
        par_desc_t *p;
-       assert(param <= SND_PCM_HW_PARAM_LAST);
-       p = &hw_pars[param];
+       assert(param <= SND_PCM_HW_INFO_LAST);
+       p = &hw_infos[param];
        switch (p->type) {
        case MASK:
                return !snd_pcm_hw_info_par_get_mask(info, param);
        case MINMAX:
        {
-               unsigned long min, max;
+               unsigned int min, max;
                snd_pcm_hw_info_par_get_minmax(info, param, &min, &max);
                return min > max;
        }
@@ -1923,7 +1934,7 @@ int snd_pcm_hw_info_par_empty(snd_pcm_hw_info_t *info, unsigned int param)
 unsigned int snd_pcm_hw_info_fail_mask(snd_pcm_hw_info_t *info)
 {
        unsigned int k, mask = 0;
-       for (k = 0; k <= SND_PCM_HW_PARAM_LAST; ++k) {
+       for (k = 0; k <= SND_PCM_HW_INFO_LAST; ++k) {
                if (snd_pcm_hw_info_par_empty(info, k))
                        mask |= 1 << k;
        }
@@ -2008,7 +2019,7 @@ int snd_pcm_hw_info_strategy1(snd_pcm_t *pcm, snd_pcm_hw_info_t *info,
 {
        snd_pcm_hw_info_t best_info;
        int param;
-       long value;
+       int value;
        unsigned int best_badness;
        unsigned int mask = ~0;
        int badness = strategy->min_badness(info, badness_max, pcm, strategy);
@@ -2053,7 +2064,7 @@ int snd_pcm_hw_info_strategy1(snd_pcm_t *pcm, snd_pcm_hw_info_t *info,
                mask &= snd_pcm_hw_info_fail_mask(&info1);
        }
        if (best_badness == UINT_MAX) {
-               for (param = 0; param <= SND_PCM_HW_PARAM_LAST; param++) {
+               for (param = 0; param <= SND_PCM_HW_INFO_LAST; param++) {
                        if (!(mask & (1 << param)))
                                continue;
                        snd_pcm_hw_info_par_copy(info, param, &info1);
@@ -2081,7 +2092,7 @@ void snd_pcm_strategy_simple_free(snd_pcm_strategy_t *strategy)
 {
        snd_pcm_strategy_simple_t *pars = strategy->private;
        int k;
-       for (k = 0; k <= SND_PCM_HW_PARAM_LAST; ++k) {
+       for (k = 0; k <= SND_PCM_HW_INFO_LAST; ++k) {
                if (pars[k].valid && pars[k].free)
                        pars[k].free(&pars[k]);
        }
@@ -2095,9 +2106,9 @@ int snd_pcm_strategy_simple_choose_param(const snd_pcm_hw_info_t *info,
        unsigned int param;
        int best_param = -1;
        const snd_pcm_strategy_simple_t *pars = strategy->private;
-       unsigned long min_choices = ULONG_MAX;
+       unsigned int min_choices = UINT_MAX;
        unsigned int min_order = UINT_MAX;
-       for (param = 0; param <= SND_PCM_HW_PARAM_LAST; ++param) {
+       for (param = 0; param <= SND_PCM_HW_INFO_LAST; ++param) {
                const snd_pcm_strategy_simple_t *p = &pars[param];
                unsigned int choices;
                if (!p->valid)
@@ -2117,9 +2128,9 @@ int snd_pcm_strategy_simple_choose_param(const snd_pcm_hw_info_t *info,
        return best_param;
 }
 
-long snd_pcm_strategy_simple_next_value(const snd_pcm_hw_info_t *info,
+int snd_pcm_strategy_simple_next_value(const snd_pcm_hw_info_t *info,
                                        unsigned int param,
-                                       long value,
+                                       int value,
                                        snd_pcm_t *pcm,
                                        const snd_pcm_strategy_t *strategy)
 {
@@ -2137,7 +2148,7 @@ int snd_pcm_strategy_simple_min_badness(const snd_pcm_hw_info_t *info,
        unsigned int param;
        unsigned int badness = 0;
        const snd_pcm_strategy_simple_t *pars = strategy->private;
-       for (param = 0; param <= SND_PCM_HW_PARAM_LAST; ++param) {
+       for (param = 0; param <= SND_PCM_HW_INFO_LAST; ++param) {
                unsigned int b;
                if (!pars[param].valid)
                        continue;
@@ -2162,8 +2173,8 @@ unsigned int snd_pcm_strategy_simple_near_min_badness(const snd_pcm_hw_info_t *i
                                                      const snd_pcm_strategy_simple_t *par)
 {
        const snd_pcm_strategy_simple_near_t *p = par->private;
-       long value = snd_pcm_hw_info_par_nearest_next(info, param, p->best, -1, pcm);
-       long diff;
+       int value = snd_pcm_hw_info_par_nearest_next(info, param, p->best, -1, pcm);
+       int diff;
        assert(value >= 0);
        diff = p->best - value;
        if (diff < 0)
@@ -2171,9 +2182,9 @@ unsigned int snd_pcm_strategy_simple_near_min_badness(const snd_pcm_hw_info_t *i
        return diff * p->mul;
 }
        
-long snd_pcm_strategy_simple_near_next_value(const snd_pcm_hw_info_t *info,
+int snd_pcm_strategy_simple_near_next_value(const snd_pcm_hw_info_t *info,
                                             unsigned int param,
-                                            long value,
+                                            int value,
                                             snd_pcm_t *pcm,
                                             const snd_pcm_strategy_simple_t *par)
 {
@@ -2203,9 +2214,9 @@ unsigned int snd_pcm_strategy_simple_choices_min_badness(const snd_pcm_hw_info_t
        return UINT_MAX;
 }
        
-long snd_pcm_strategy_simple_choices_next_value(const snd_pcm_hw_info_t *info,
+int snd_pcm_strategy_simple_choices_next_value(const snd_pcm_hw_info_t *info,
                                                unsigned int param,
-                                               long value,
+                                               int value,
                                                snd_pcm_t *pcm ATTRIBUTE_UNUSED,
                                                const snd_pcm_strategy_simple_t *par)
 {
@@ -2213,14 +2224,14 @@ long snd_pcm_strategy_simple_choices_next_value(const snd_pcm_hw_info_t *info,
        unsigned int k = 0;
        if (value >= 0) {
                for (; k < p->count; ++k) {
-                       if (p->choices[k].value == (unsigned long) value) {
+                       if (p->choices[k].value == (unsigned int) value) {
                                k++;
                                break;
                        }
                }
        }
        for (; k < p->count; ++k) {
-               unsigned long v = p->choices[k].value;
+               unsigned int v = p->choices[k].value;
                if (snd_pcm_hw_info_par_check(info, param, v))
                        return v;
        }
@@ -2242,7 +2253,7 @@ int snd_pcm_strategy_simple(snd_pcm_strategy_t **strategyp,
        snd_pcm_strategy_simple_t *data;
        snd_pcm_strategy_t *s;
        assert(strategyp);
-       data = calloc(SND_PCM_HW_PARAM_LAST + 1, sizeof(*data));
+       data = calloc(SND_PCM_HW_INFO_LAST + 1, sizeof(*data));
        if (!data)
                return -ENOMEM;
        s = calloc(1, sizeof(*s));
@@ -2264,13 +2275,13 @@ int snd_pcm_strategy_simple(snd_pcm_strategy_t **strategyp,
 int snd_pcm_strategy_simple_near(snd_pcm_strategy_t *strategy,
                                 int order,
                                 unsigned int param,
-                                unsigned long best,
+                                unsigned int best,
                                 unsigned int mul)
 {
        snd_pcm_strategy_simple_t *s = strategy->private;
        snd_pcm_strategy_simple_near_t *data;
        assert(strategy);
-       assert(param <= SND_PCM_HW_PARAM_LAST);
+       assert(param <= SND_PCM_HW_INFO_LAST);
        assert(!s->valid);
        data = calloc(1, sizeof(*data));
        if (!data)
@@ -2296,7 +2307,7 @@ int snd_pcm_strategy_simple_choices(snd_pcm_strategy_t *strategy,
        snd_pcm_strategy_simple_t *s = strategy->private;
        snd_pcm_strategy_simple_choices_t *data;
        assert(strategy);
-       assert(param <= SND_PCM_HW_PARAM_LAST);
+       assert(param <= SND_PCM_HW_INFO_LAST);
        assert(!s->valid);
        data = calloc(1, sizeof(*data));
        if (!data)
@@ -2316,8 +2327,8 @@ int snd_pcm_strategy_simple_choices(snd_pcm_strategy_t *strategy,
 int snd_pcm_dump_hw_info(snd_pcm_hw_info_t *info, FILE *fp)
 {
        unsigned int param;
-       for (param = 0; param <= SND_PCM_HW_PARAM_LAST; param++) {
-               fprintf(fp, "%s: ", snd_pcm_hw_param_names[param]);
+       for (param = 0; param <= SND_PCM_HW_INFO_LAST; param++) {
+               fprintf(fp, "%s: ", snd_pcm_hw_info_names[param]);
                snd_pcm_hw_info_par_dump(info, param, fp);
                putc('\n', fp);
        }
@@ -2334,7 +2345,7 @@ int snd_pcm_hw_info_try_explain_failure1(snd_pcm_t *pcm,
        snd_pcm_hw_info_t i;
        if (depth < 1)
                return -ENOENT;
-       for (param = 0; param <= SND_PCM_HW_PARAM_LAST; param++) {
+       for (param = 0; param <= SND_PCM_HW_INFO_LAST; param++) {
                int err;
                i = *success;
                snd_pcm_hw_info_par_copy(&i, param, fail);
@@ -2342,7 +2353,7 @@ int snd_pcm_hw_info_try_explain_failure1(snd_pcm_t *pcm,
                if (err == 0 && 
                    snd_pcm_hw_info_try_explain_failure1(pcm, fail, &i, depth - 1, fp) < 0)
                        continue;
-               fprintf(fp, "%s: ", snd_pcm_hw_param_names[param]);
+               fprintf(fp, "%s: ", snd_pcm_hw_info_names[param]);
                snd_pcm_hw_info_par_dump(fail, param, fp);
                putc('\n', fp);
                return 0;
@@ -2363,10 +2374,10 @@ int snd_pcm_hw_info_try_explain_failure(snd_pcm_t *pcm,
         fail_mask = snd_pcm_hw_info_fail_mask(fail);
        if (fail_mask) {
                unsigned int param;
-               for (param = 0; param <= SND_PCM_HW_PARAM_LAST; param++) {
+               for (param = 0; param <= SND_PCM_HW_INFO_LAST; param++) {
                        if (!(fail_mask & (1 << param)))
                                continue;
-                       fprintf(fp, "%s: ", snd_pcm_hw_param_names[param]);
+                       fprintf(fp, "%s: ", snd_pcm_hw_info_names[param]);
                        snd_pcm_hw_info_par_dump(fail, param, fp);
                        putc('\n', fp);
                }
index 369f71865fa8e4eebf7ed6a5c4ae09299cecfe63..82b8f7de2a0252cd6c6077d5c2566be85b7d42bf 100644 (file)
@@ -276,3 +276,28 @@ static inline ssize_t _snd_pcm_readn(snd_pcm_t *pcm, void **bufs, size_t size)
        return pcm->fast_ops->readn(pcm->fast_op_arg, bufs, size);
 }
 
+static inline ssize_t muldiv(ssize_t a, ssize_t b, ssize_t d, ssize_t corr)
+{
+       double v = ((double) a * b + corr) / d;
+       if (v > LONG_MAX)
+               return LONG_MAX;
+       if (v < LONG_MIN)
+               return LONG_MIN;
+       return v;
+}
+
+static inline ssize_t muldiv_down(ssize_t a, ssize_t b, ssize_t d)
+{
+       return muldiv(a, b, d, 0);
+}
+
+static inline ssize_t muldiv_up(ssize_t a, ssize_t b, ssize_t d)
+{
+       return muldiv(a, b, d, d - 1);
+}
+
+static inline ssize_t muldiv_near(ssize_t a, ssize_t b, ssize_t d)
+{
+       return muldiv(a, b, d, d / 2);
+}
+
index c67b992581994b2c812ce9f86da62f4d487f5f05..82c50cc0e3be1d8792bc4ecf63b246e6762bbb96 100644 (file)
@@ -125,12 +125,12 @@ static int snd_pcm_multi_hw_info(snd_pcm_t *pcm, snd_pcm_hw_info_t *info)
                            i.subformat_mask != sinfo.subformat_mask ||
                            i.rate_min != sinfo.rate_min ||
                            i.rate_max != sinfo.rate_max ||
-                           i.fragment_size_min != sinfo.fragment_size_min ||
-                           i.fragment_size_max != sinfo.fragment_size_max ||
+                           i.fragment_length_min != sinfo.fragment_length_min ||
+                           i.fragment_length_max != sinfo.fragment_length_max ||
                            i.fragments_min != sinfo.fragments_min ||
                            i.fragments_max != sinfo.fragments_max ||
-                           i.buffer_size_min != sinfo.buffer_size_min ||
-                           i.buffer_size_max != sinfo.buffer_size_max)
+                           i.buffer_length_min != sinfo.buffer_length_min ||
+                           i.buffer_length_max != sinfo.buffer_length_max)
                                changed++;
                        saccess_mask &= sinfo.access_mask;
                        i = sinfo;
index 452705ce6315c121bd14632b5c40d6815edfef82..28b2af9f25cfafbc240f491794c7a6d83d9fcb87 100644 (file)
@@ -154,8 +154,6 @@ static int snd_pcm_plug_hw_info(snd_pcm_t *pcm, snd_pcm_hw_info_t *info)
        snd_pcm_t *slave = plug->req_slave;
        snd_pcm_hw_info_t sinfo;
        int err;
-       size_t size;
-       unsigned int n;
        
        info->access_mask &= (SND_PCM_ACCBIT_MMAP_INTERLEAVED | 
                              SND_PCM_ACCBIT_RW_INTERLEAVED |
@@ -193,74 +191,16 @@ static int snd_pcm_plug_hw_info(snd_pcm_t *pcm, snd_pcm_hw_info_t *info)
        sinfo.channels_max = UINT_MAX;
        sinfo.rate_min = RATE_MIN;
        sinfo.rate_max = RATE_MAX;
-       sinfo.fragment_size_min = muldiv_down(info->fragment_size_min, sinfo.rate_min, info->rate_max);
-       sinfo.fragment_size_max = muldiv_up(info->fragment_size_max, sinfo.rate_max, info->rate_min);
-       sinfo.buffer_size_min = muldiv_down(info->buffer_size_min, sinfo.rate_min, info->rate_max);
-       sinfo.buffer_size_max = muldiv_up(info->buffer_size_max, sinfo.rate_max, info->rate_min);
-
-       /* FIXME: tricky here. This is not the right way to cope with this */
-       if (info->rate_min == info->rate_max) {
-               snd_pcm_hw_info_t i1 = sinfo;
-               snd_pcm_hw_info_t i2 = sinfo;
-               int err1, err2;
-               unsigned int rate = info->rate_min;
-               i1.rate_max = rate;
-               err1 = snd_pcm_hw_info(slave, &i1);
-               if (err1 < 0 || rate - i1.rate_max > 1) {
-                       i2.rate_min = rate + 1;
-                       err2 = snd_pcm_hw_info(slave, &i2);
-               } else
-                       err2 = -EINVAL;
-               if (err1 < 0) {
-                       sinfo = i2;
-                       if (err2 >= 0)
-                               sinfo.rate_max = sinfo.rate_min;
-                       err = err2;
-               } else {
-                       if (err2 < 0 ||
-                           rate - i1.rate_max <= i2.rate_min - rate) {
-                               sinfo = i1;
-                               sinfo.rate_min = sinfo.rate_max;
-                               err = err1;
-                       } else {
-                               sinfo = i2;
-                               sinfo.rate_max = sinfo.rate_min;
-                               err = err2;
-                       }
-               }
-       } else
-               err = snd_pcm_hw_info(slave, &sinfo);
+
+       err = snd_pcm_hw_info(slave, &sinfo);
        info->subformat_mask = sinfo.subformat_mask;
+       info->fragment_length_min = sinfo.fragment_length_min;
+       info->fragment_length_max = sinfo.fragment_length_max;
        info->fragments_min = sinfo.fragments_min;
        info->fragments_max = sinfo.fragments_max;
+       info->buffer_length_min = sinfo.buffer_length_min;
+       info->buffer_length_max = sinfo.buffer_length_max;
        
-       size = muldiv_down(sinfo.fragment_size_min, info->rate_min, sinfo.rate_max);
-       if (info->fragment_size_min < size)
-               info->fragment_size_min = size;
-       size = muldiv_up(sinfo.fragment_size_max, info->rate_max, sinfo.rate_min);
-       if (info->fragment_size_max > size)
-               info->fragment_size_max = size;
-       if (info->fragment_size_min > info->fragment_size_max)
-               return -EINVAL;
-
-       size = muldiv_down(sinfo.buffer_size_min, info->rate_min, sinfo.rate_max);
-       if (info->buffer_size_min < size)
-               info->buffer_size_min = size;
-       size = muldiv_up(sinfo.buffer_size_max, info->rate_max, sinfo.rate_min);
-       if (info->buffer_size_max > size)
-               info->buffer_size_max = size;
-       if (info->buffer_size_min > info->buffer_size_max)
-               return -EINVAL;
-
-       n = info->buffer_size_min / info->fragment_size_max;
-       if (info->fragments_min < n)
-               info->fragments_min = n;
-       n = info->buffer_size_max / info->fragment_size_min;
-       if (info->fragments_max > n)
-               info->fragments_max = n;
-       if (info->fragments_min > info->fragments_max)
-               return -EINVAL;
-
        if (err < 0)
                return err;
        info->info = sinfo.info & ~(SND_PCM_INFO_MMAP | SND_PCM_INFO_MMAP_VALID);
@@ -484,10 +424,6 @@ static int snd_pcm_plug_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
        sinfo.rate_max = RATE_MAX;
        sinfo.fragments_min = params->fragments;
        sinfo.fragments_max = params->fragments;
-       sinfo.fragment_size_min = 1;
-       sinfo.fragment_size_max = ULONG_MAX;
-       sinfo.buffer_size_min = 1;
-       sinfo.buffer_size_max = ULONG_MAX;
        err = snd_pcm_strategy_simple(&strategy, 1000000, 2000000);
        if (err < 0)
                return err;
index fc449bf286ae23f5e005d480734965939d66df94..ec40d807560b48c6d2eda7d914cd89ceb9517308 100644 (file)
@@ -74,31 +74,6 @@ int conv_index(int src_format, int dst_format);
 
 extern snd_pcm_fast_ops_t snd_pcm_plugin_fast_ops;
 
-static inline ssize_t muldiv(ssize_t a, ssize_t b, ssize_t d, ssize_t corr)
-{
-       double v = ((double) a * b + corr) / d;
-       if (v > LONG_MAX)
-               return LONG_MAX;
-       if (v < LONG_MIN)
-               return LONG_MIN;
-       return v;
-}
-
-static inline ssize_t muldiv_down(ssize_t a, ssize_t b, ssize_t d)
-{
-       return muldiv(a, b, d, 0);
-}
-
-static inline ssize_t muldiv_up(ssize_t a, ssize_t b, ssize_t d)
-{
-       return muldiv(a, b, d, d - 1);
-}
-
-static inline ssize_t muldiv_near(ssize_t a, ssize_t b, ssize_t d)
-{
-       return muldiv(a, b, d, d / 2);
-}
-
 #define RATE_MIN 4000
 #define RATE_MAX 192000
 
index f64ab88951db9462fe08e67d2c74b74853f9a0d2..231c83c8b0cdeb206d57b31848125aed102fa530 100644 (file)
@@ -236,9 +236,8 @@ static int snd_pcm_rate_close(snd_pcm_t *pcm)
 static int snd_pcm_rate_hw_info(snd_pcm_t *pcm, snd_pcm_hw_info_t * info)
 {
        snd_pcm_rate_t *rate = pcm->private;
-       snd_pcm_hw_info_t sinfo;
-       unsigned int access_mask;
-       size_t size;
+       unsigned int access_mask, format_mask;
+       unsigned int rate_min, rate_max;
        int err;
        info->access_mask &= (SND_PCM_ACCBIT_MMAP_INTERLEAVED | 
                              SND_PCM_ACCBIT_RW_INTERLEAVED |
@@ -247,59 +246,36 @@ static int snd_pcm_rate_hw_info(snd_pcm_t *pcm, snd_pcm_hw_info_t * info)
        access_mask = info->access_mask;
        if (access_mask == 0)
                return -EINVAL;
+
        info->format_mask &= SND_PCM_FMTBIT_LINEAR;
-       if (info->format_mask == 0)
-               return -EINVAL;
-       info->subformat_mask &= SND_PCM_SUBFMTBIT_STD;
-       if (info->subformat_mask == 0)
+       format_mask = info->format_mask;
+       if (format_mask == 0)
                return -EINVAL;
+
        if (info->rate_min < RATE_MIN)
                info->rate_min = RATE_MIN;
        if (info->rate_max > RATE_MAX)
                info->rate_max = RATE_MAX;
-       if (info->rate_max < info->rate_min)
+       rate_min = info->rate_min;
+       rate_max = info->rate_max;
+       if (rate_max < rate_min)
                return -EINVAL;
-
-       sinfo = *info;
-       sinfo.access_mask = SND_PCM_ACCBIT_MMAP;
+       
+       info->access_mask = SND_PCM_ACCBIT_MMAP;
        if (rate->sformat >= 0)
-               sinfo.format_mask = 1U << rate->sformat;
-       sinfo.rate_min = rate->srate;
-       sinfo.rate_max = rate->srate;
-       sinfo.fragment_size_min = muldiv_down(info->fragment_size_min, sinfo.rate_min, info->rate_max);
-       sinfo.fragment_size_max = muldiv_up(info->fragment_size_max, sinfo.rate_max, info->rate_min);
-       sinfo.buffer_size_min = muldiv_down(info->buffer_size_min, sinfo.rate_min, info->rate_max);
-       sinfo.buffer_size_max = muldiv_up(info->buffer_size_max, sinfo.rate_max, info->rate_min);
+               info->format_mask = 1U << rate->sformat;
+       info->rate_min = rate->srate;
+       info->rate_max = rate->srate;
                
-       err = snd_pcm_hw_info(rate->plug.slave, &sinfo);
-       if (rate->sformat < 0)
-               info->format_mask = sinfo.format_mask;
-       info->channels_min = sinfo.channels_min;
-       info->channels_max = sinfo.channels_max;
-       info->fragments_min = sinfo.fragments_min;
-       info->fragments_max = sinfo.fragments_max;
-
-       size = muldiv_down(sinfo.fragment_size_min, info->rate_min, sinfo.rate_max);
-       if (info->fragment_size_min < size)
-               info->fragment_size_min = size;
-       size = muldiv_up(sinfo.fragment_size_max, info->rate_max, sinfo.rate_min);
-       if (info->fragment_size_max > size)
-               info->fragment_size_max = size;
-       if (info->fragment_size_min > info->fragment_size_max)
-               return -EINVAL;
+       err = snd_pcm_hw_info(rate->plug.slave, info);
+       if (rate->sformat >= 0)
+               info->format_mask = format_mask;
+       info->rate_min = rate_min;
+       info->rate_max = rate_max;
 
-       size = muldiv_down(sinfo.buffer_size_min, info->rate_min, sinfo.rate_max);
-       if (info->buffer_size_min < size)
-               info->buffer_size_min = size;
-       size = muldiv_up(sinfo.buffer_size_max, info->rate_max, sinfo.rate_min);
-       if (info->buffer_size_max > size)
-               info->buffer_size_max = size;
-       if (info->buffer_size_min > info->buffer_size_max)
-               return -EINVAL;
        if (err < 0)
                return err;
-
-       info->info = sinfo.info & ~(SND_PCM_INFO_MMAP | SND_PCM_INFO_MMAP_VALID);
+       info->info &= ~(SND_PCM_INFO_MMAP | SND_PCM_INFO_MMAP_VALID);
        snd_pcm_hw_info_complete(info);
        return 0;
 }
@@ -320,10 +296,6 @@ static int snd_pcm_rate_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
        sinfo.access_mask = SND_PCM_ACCBIT_MMAP;
        sinfo.rate_min = rate->srate;
        sinfo.rate_max = rate->srate;
-       sinfo.fragment_size_min = muldiv_down(params->fragment_size, rate->srate, params->rate);
-       sinfo.fragment_size_max = muldiv_up(params->fragment_size, rate->srate, params->rate);
-       sinfo.buffer_size_min = muldiv_down(params->fragment_size * params->fragments, rate->srate, params->rate);
-       sinfo.buffer_size_max = muldiv_up(params->fragment_size * params->fragments, rate->srate, params->rate);
        err = snd_pcm_hw_params_info(slave, &sparams, &sinfo);
        params->fail_mask = sparams.fail_mask;
        if (err < 0)