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;
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)
}
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);
}
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;
}
-