]> git.alsa-project.org Git - alsa-lib.git/commitdiff
Fixed rounding issues
authorAbramo Bagnara <abramo@alsa-project.org>
Sun, 10 Dec 2000 12:08:20 +0000 (12:08 +0000)
committerAbramo Bagnara <abramo@alsa-project.org>
Sun, 10 Dec 2000 12:08:20 +0000 (12:08 +0000)
src/pcm/pcm.c
src/pcm/pcm_local.h

index c6ea9929b31d11295a18c2397fba3b73d12b6dea..ad2641240a60e302d8f03cb43dfee915b863115e 100644 (file)
@@ -133,6 +133,7 @@ void snd_pcm_hw_info_any(snd_pcm_hw_info_t *info)
 
 void snd_pcm_hw_params_to_info(snd_pcm_hw_params_t *params, snd_pcm_hw_info_t *info)
 {
+       int r;
        assert(info && params);
        info->flags = 0;
        info->access_mask = 1U << params->access;
@@ -140,9 +141,15 @@ 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_length_min = info->fragment_length_max = muldiv_down(params->fragment_size, 1000000, params->rate);
+       info->fragment_length_min = muldiv_down(params->fragment_size, 1000000, params->rate);
+       info->fragment_length_max = muldiv(params->fragment_size + 1, 1000000, params->rate, &r);
+       if (r == 0)
+               info->fragment_length_max--;
        info->fragments_min = info->fragments_max = params->fragments;
-       info->buffer_length_min = info->buffer_length_max = muldiv_down(params->fragment_size * params->fragments, 1000000, params->rate);
+       info->buffer_length_min = muldiv_down(params->fragment_size * params->fragments, 1000000, params->rate);
+       info->buffer_length_max = muldiv((params->fragment_size + 1) * params->fragments, 1000000, params->rate, &r);
+       if (r  == 0)
+               info->buffer_length_max--;
 }
 
 int snd_pcm_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t *params)
@@ -1921,7 +1928,8 @@ int snd_pcm_hw_info_to_params(snd_pcm_t *pcm, snd_pcm_hw_info_t *info, snd_pcm_h
        }
        assert(info->fragments_min <= info->fragments_max);
        if (info->fragments_min < info->fragments_max) {
-               info->fragments_max = info->fragments_min;
+               /* Defaults to maximum use of buffer */
+               info->fragments_min = info->fragments_max;
                err = snd_pcm_hw_info(pcm, info);
                assert(err >= 0);
        }
index c4c047a8e64547663ebcff9f71320b3ea5ee1900..ecb671b6a093fc8ad54b00ba620ea4a1310e0176 100644 (file)
@@ -280,28 +280,39 @@ 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)
+static inline int muldiv(int a, int b, int c, int *r)
 {
-       double v = ((double) a * b + corr) / d;
-       if (v > LONG_MAX)
-               return LONG_MAX;
-       if (v < LONG_MIN)
-               return LONG_MIN;
+       int64_t n = (int64_t)a * b;
+       int64_t v = n / c;
+       if (v > INT_MAX) {
+               *r = 0;
+               return INT_MAX;
+       }
+       if (v < INT_MIN) {
+               *r = 0;
+               return INT_MIN;
+       }
+       *r = n % c;
        return v;
 }
 
-static inline ssize_t muldiv_down(ssize_t a, ssize_t b, ssize_t d)
+static inline int muldiv_down(int a, int b, int c)
 {
-       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);
+       int64_t v = (int64_t)a * b / c;
+       if (v > INT_MAX) {
+               return INT_MAX;
+       }
+       if (v < INT_MIN) {
+               return INT_MIN;
+       }
+       return v;
 }
 
-static inline ssize_t muldiv_near(ssize_t a, ssize_t b, ssize_t d)
+static inline int muldiv_near(int a, int b, int c)
 {
-       return muldiv(a, b, d, d / 2);
+       int r;
+       int n = muldiv(a, b, c, &r);
+       if (r >= (c + 1) / 2)
+               n++;
+       return n;
 }
-