From b5e96c01619ff66e1a2df0303ff1f0c87378561a Mon Sep 17 00:00:00 2001 From: Abramo Bagnara Date: Sun, 10 Dec 2000 12:08:20 +0000 Subject: [PATCH] Fixed rounding issues --- src/pcm/pcm.c | 14 +++++++++++--- src/pcm/pcm_local.h | 43 +++++++++++++++++++++++++++---------------- 2 files changed, 38 insertions(+), 19 deletions(-) diff --git a/src/pcm/pcm.c b/src/pcm/pcm.c index c6ea9929..ad264124 100644 --- a/src/pcm/pcm.c +++ b/src/pcm/pcm.c @@ -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); } diff --git a/src/pcm/pcm_local.h b/src/pcm/pcm_local.h index c4c047a8..ecb671b6 100644 --- a/src/pcm/pcm_local.h +++ b/src/pcm/pcm_local.h @@ -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; } - -- 2.47.1