mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2025-10-29 05:40:25 -04:00
Fixed rounding issues
This commit is contained in:
parent
5465c299ab
commit
b5e96c0161
2 changed files with 38 additions and 19 deletions
|
|
@ -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)
|
void snd_pcm_hw_params_to_info(snd_pcm_hw_params_t *params, snd_pcm_hw_info_t *info)
|
||||||
{
|
{
|
||||||
|
int r;
|
||||||
assert(info && params);
|
assert(info && params);
|
||||||
info->flags = 0;
|
info->flags = 0;
|
||||||
info->access_mask = 1U << params->access;
|
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->subformat_mask = 1U << params->subformat;
|
||||||
info->channels_min = info->channels_max = params->channels;
|
info->channels_min = info->channels_max = params->channels;
|
||||||
info->rate_min = info->rate_max = params->rate;
|
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->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)
|
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);
|
assert(info->fragments_min <= info->fragments_max);
|
||||||
if (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);
|
err = snd_pcm_hw_info(pcm, info);
|
||||||
assert(err >= 0);
|
assert(err >= 0);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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);
|
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;
|
int64_t n = (int64_t)a * b;
|
||||||
if (v > LONG_MAX)
|
int64_t v = n / c;
|
||||||
return LONG_MAX;
|
if (v > INT_MAX) {
|
||||||
if (v < LONG_MIN)
|
*r = 0;
|
||||||
return LONG_MIN;
|
return INT_MAX;
|
||||||
|
}
|
||||||
|
if (v < INT_MIN) {
|
||||||
|
*r = 0;
|
||||||
|
return INT_MIN;
|
||||||
|
}
|
||||||
|
*r = n % c;
|
||||||
return v;
|
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);
|
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_up(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 - 1);
|
int r;
|
||||||
|
int n = muldiv(a, b, c, &r);
|
||||||
|
if (r >= (c + 1) / 2)
|
||||||
|
n++;
|
||||||
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline ssize_t muldiv_near(ssize_t a, ssize_t b, ssize_t d)
|
|
||||||
{
|
|
||||||
return muldiv(a, b, d, d / 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue