1d5ac70f0Sopenharmony_ci/* 2d5ac70f0Sopenharmony_ci * Interval functions 3d5ac70f0Sopenharmony_ci * Copyright (c) 2000 by Abramo Bagnara <abramo@alsa-project.org> 4d5ac70f0Sopenharmony_ci * 5d5ac70f0Sopenharmony_ci * 6d5ac70f0Sopenharmony_ci * This library is free software; you can redistribute it and/or modify 7d5ac70f0Sopenharmony_ci * it under the terms of the GNU Lesser General Public License as 8d5ac70f0Sopenharmony_ci * published by the Free Software Foundation; either version 2.1 of 9d5ac70f0Sopenharmony_ci * the License, or (at your option) any later version. 10d5ac70f0Sopenharmony_ci * 11d5ac70f0Sopenharmony_ci * This program is distributed in the hope that it will be useful, 12d5ac70f0Sopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 13d5ac70f0Sopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14d5ac70f0Sopenharmony_ci * GNU Lesser General Public License for more details. 15d5ac70f0Sopenharmony_ci * 16d5ac70f0Sopenharmony_ci * You should have received a copy of the GNU Lesser General Public 17d5ac70f0Sopenharmony_ci * License along with this library; if not, write to the Free Software 18d5ac70f0Sopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19d5ac70f0Sopenharmony_ci * 20d5ac70f0Sopenharmony_ci */ 21d5ac70f0Sopenharmony_ci 22d5ac70f0Sopenharmony_ci#define SND_INTERVAL_C 23d5ac70f0Sopenharmony_ci#define SND_INTERVAL_INLINE 24d5ac70f0Sopenharmony_ci 25d5ac70f0Sopenharmony_ci#include "pcm_local.h" 26d5ac70f0Sopenharmony_ci#include <sys/types.h> 27d5ac70f0Sopenharmony_ci#include <limits.h> 28d5ac70f0Sopenharmony_ci 29d5ac70f0Sopenharmony_cistatic inline void div64_32(uint64_t *n, uint32_t d, uint32_t *rem) 30d5ac70f0Sopenharmony_ci{ 31d5ac70f0Sopenharmony_ci *rem = *n % d; 32d5ac70f0Sopenharmony_ci *n /= d; 33d5ac70f0Sopenharmony_ci} 34d5ac70f0Sopenharmony_ci 35d5ac70f0Sopenharmony_cistatic inline unsigned int div32(unsigned int a, unsigned int b, 36d5ac70f0Sopenharmony_ci unsigned int *r) 37d5ac70f0Sopenharmony_ci{ 38d5ac70f0Sopenharmony_ci if (b == 0) { 39d5ac70f0Sopenharmony_ci *r = 0; 40d5ac70f0Sopenharmony_ci return UINT_MAX; 41d5ac70f0Sopenharmony_ci } 42d5ac70f0Sopenharmony_ci *r = a % b; 43d5ac70f0Sopenharmony_ci return a / b; 44d5ac70f0Sopenharmony_ci} 45d5ac70f0Sopenharmony_ci 46d5ac70f0Sopenharmony_cistatic inline unsigned int div_down(unsigned int a, unsigned int b) 47d5ac70f0Sopenharmony_ci{ 48d5ac70f0Sopenharmony_ci if (b == 0) 49d5ac70f0Sopenharmony_ci return UINT_MAX; 50d5ac70f0Sopenharmony_ci return a / b; 51d5ac70f0Sopenharmony_ci} 52d5ac70f0Sopenharmony_ci 53d5ac70f0Sopenharmony_cistatic inline unsigned int div_up(unsigned int a, unsigned int b) 54d5ac70f0Sopenharmony_ci{ 55d5ac70f0Sopenharmony_ci unsigned int r; 56d5ac70f0Sopenharmony_ci unsigned int q; 57d5ac70f0Sopenharmony_ci if (b == 0) 58d5ac70f0Sopenharmony_ci return UINT_MAX; 59d5ac70f0Sopenharmony_ci q = div32(a, b, &r); 60d5ac70f0Sopenharmony_ci if (r) 61d5ac70f0Sopenharmony_ci ++q; 62d5ac70f0Sopenharmony_ci return q; 63d5ac70f0Sopenharmony_ci} 64d5ac70f0Sopenharmony_ci 65d5ac70f0Sopenharmony_cistatic inline unsigned int mul(unsigned int a, unsigned int b) 66d5ac70f0Sopenharmony_ci{ 67d5ac70f0Sopenharmony_ci if (a == 0) 68d5ac70f0Sopenharmony_ci return 0; 69d5ac70f0Sopenharmony_ci if (div_down(UINT_MAX, a) < b) 70d5ac70f0Sopenharmony_ci return UINT_MAX; 71d5ac70f0Sopenharmony_ci return a * b; 72d5ac70f0Sopenharmony_ci} 73d5ac70f0Sopenharmony_ci 74d5ac70f0Sopenharmony_cistatic inline unsigned int add(unsigned int a, unsigned int b) 75d5ac70f0Sopenharmony_ci{ 76d5ac70f0Sopenharmony_ci if (a >= UINT_MAX - b) 77d5ac70f0Sopenharmony_ci return UINT_MAX; 78d5ac70f0Sopenharmony_ci return a + b; 79d5ac70f0Sopenharmony_ci} 80d5ac70f0Sopenharmony_ci 81d5ac70f0Sopenharmony_cistatic inline unsigned int sub(unsigned int a, unsigned int b) 82d5ac70f0Sopenharmony_ci{ 83d5ac70f0Sopenharmony_ci if (a > b) 84d5ac70f0Sopenharmony_ci return a - b; 85d5ac70f0Sopenharmony_ci return 0; 86d5ac70f0Sopenharmony_ci} 87d5ac70f0Sopenharmony_ci 88d5ac70f0Sopenharmony_cistatic inline unsigned int muldiv32(unsigned int a, unsigned int b, 89d5ac70f0Sopenharmony_ci unsigned int c, unsigned int *r) 90d5ac70f0Sopenharmony_ci{ 91d5ac70f0Sopenharmony_ci uint64_t n = (uint64_t) a * b; 92d5ac70f0Sopenharmony_ci if (c == 0) { 93d5ac70f0Sopenharmony_ci assert(n > 0); 94d5ac70f0Sopenharmony_ci *r = 0; 95d5ac70f0Sopenharmony_ci return UINT_MAX; 96d5ac70f0Sopenharmony_ci } 97d5ac70f0Sopenharmony_ci div64_32(&n, c, r); 98d5ac70f0Sopenharmony_ci if (n >= UINT_MAX) { 99d5ac70f0Sopenharmony_ci *r = 0; 100d5ac70f0Sopenharmony_ci return UINT_MAX; 101d5ac70f0Sopenharmony_ci } 102d5ac70f0Sopenharmony_ci return n; 103d5ac70f0Sopenharmony_ci} 104d5ac70f0Sopenharmony_ci 105d5ac70f0Sopenharmony_ciint snd_interval_refine_min(snd_interval_t *i, unsigned int min, int openmin) 106d5ac70f0Sopenharmony_ci{ 107d5ac70f0Sopenharmony_ci int changed = 0; 108d5ac70f0Sopenharmony_ci if (snd_interval_empty(i)) 109d5ac70f0Sopenharmony_ci return -ENOENT; 110d5ac70f0Sopenharmony_ci if (i->min < min) { 111d5ac70f0Sopenharmony_ci i->min = min; 112d5ac70f0Sopenharmony_ci i->openmin = openmin; 113d5ac70f0Sopenharmony_ci changed = 1; 114d5ac70f0Sopenharmony_ci } else if (i->min == min && !i->openmin && openmin) { 115d5ac70f0Sopenharmony_ci i->openmin = 1; 116d5ac70f0Sopenharmony_ci changed = 1; 117d5ac70f0Sopenharmony_ci } 118d5ac70f0Sopenharmony_ci if (i->integer) { 119d5ac70f0Sopenharmony_ci if (i->openmin) { 120d5ac70f0Sopenharmony_ci i->min++; 121d5ac70f0Sopenharmony_ci i->openmin = 0; 122d5ac70f0Sopenharmony_ci } 123d5ac70f0Sopenharmony_ci } 124d5ac70f0Sopenharmony_ci if (snd_interval_checkempty(i)) { 125d5ac70f0Sopenharmony_ci snd_interval_none(i); 126d5ac70f0Sopenharmony_ci return -EINVAL; 127d5ac70f0Sopenharmony_ci } 128d5ac70f0Sopenharmony_ci return changed; 129d5ac70f0Sopenharmony_ci} 130d5ac70f0Sopenharmony_ci 131d5ac70f0Sopenharmony_ciint snd_interval_refine_max(snd_interval_t *i, unsigned int max, int openmax) 132d5ac70f0Sopenharmony_ci{ 133d5ac70f0Sopenharmony_ci int changed = 0; 134d5ac70f0Sopenharmony_ci if (snd_interval_empty(i)) 135d5ac70f0Sopenharmony_ci return -ENOENT; 136d5ac70f0Sopenharmony_ci if (i->max > max) { 137d5ac70f0Sopenharmony_ci i->max = max; 138d5ac70f0Sopenharmony_ci i->openmax = openmax; 139d5ac70f0Sopenharmony_ci changed = 1; 140d5ac70f0Sopenharmony_ci } else if (i->max == max && !i->openmax && openmax) { 141d5ac70f0Sopenharmony_ci i->openmax = 1; 142d5ac70f0Sopenharmony_ci changed = 1; 143d5ac70f0Sopenharmony_ci } 144d5ac70f0Sopenharmony_ci if (i->integer) { 145d5ac70f0Sopenharmony_ci if (i->openmax) { 146d5ac70f0Sopenharmony_ci i->max--; 147d5ac70f0Sopenharmony_ci i->openmax = 0; 148d5ac70f0Sopenharmony_ci } 149d5ac70f0Sopenharmony_ci } 150d5ac70f0Sopenharmony_ci if (snd_interval_checkempty(i)) { 151d5ac70f0Sopenharmony_ci snd_interval_none(i); 152d5ac70f0Sopenharmony_ci return -EINVAL; 153d5ac70f0Sopenharmony_ci } 154d5ac70f0Sopenharmony_ci return changed; 155d5ac70f0Sopenharmony_ci} 156d5ac70f0Sopenharmony_ci 157d5ac70f0Sopenharmony_ci/* r <- v */ 158d5ac70f0Sopenharmony_ciint snd_interval_refine(snd_interval_t *i, const snd_interval_t *v) 159d5ac70f0Sopenharmony_ci{ 160d5ac70f0Sopenharmony_ci int changed = 0; 161d5ac70f0Sopenharmony_ci if (snd_interval_empty(i)) 162d5ac70f0Sopenharmony_ci return -ENOENT; 163d5ac70f0Sopenharmony_ci if (i->min < v->min) { 164d5ac70f0Sopenharmony_ci i->min = v->min; 165d5ac70f0Sopenharmony_ci i->openmin = v->openmin; 166d5ac70f0Sopenharmony_ci changed = 1; 167d5ac70f0Sopenharmony_ci } else if (i->min == v->min && !i->openmin && v->openmin) { 168d5ac70f0Sopenharmony_ci i->openmin = 1; 169d5ac70f0Sopenharmony_ci changed = 1; 170d5ac70f0Sopenharmony_ci } 171d5ac70f0Sopenharmony_ci if (i->max > v->max) { 172d5ac70f0Sopenharmony_ci i->max = v->max; 173d5ac70f0Sopenharmony_ci i->openmax = v->openmax; 174d5ac70f0Sopenharmony_ci changed = 1; 175d5ac70f0Sopenharmony_ci } else if (i->max == v->max && !i->openmax && v->openmax) { 176d5ac70f0Sopenharmony_ci i->openmax = 1; 177d5ac70f0Sopenharmony_ci changed = 1; 178d5ac70f0Sopenharmony_ci } 179d5ac70f0Sopenharmony_ci if (!i->integer && v->integer) { 180d5ac70f0Sopenharmony_ci i->integer = 1; 181d5ac70f0Sopenharmony_ci changed = 1; 182d5ac70f0Sopenharmony_ci } 183d5ac70f0Sopenharmony_ci if (i->integer) { 184d5ac70f0Sopenharmony_ci if (i->openmin) { 185d5ac70f0Sopenharmony_ci i->min++; 186d5ac70f0Sopenharmony_ci i->openmin = 0; 187d5ac70f0Sopenharmony_ci } 188d5ac70f0Sopenharmony_ci if (i->openmax) { 189d5ac70f0Sopenharmony_ci i->max--; 190d5ac70f0Sopenharmony_ci i->openmax = 0; 191d5ac70f0Sopenharmony_ci } 192d5ac70f0Sopenharmony_ci } else if (!i->openmin && !i->openmax && i->min == i->max) 193d5ac70f0Sopenharmony_ci i->integer = 1; 194d5ac70f0Sopenharmony_ci if (snd_interval_checkempty(i)) { 195d5ac70f0Sopenharmony_ci snd_interval_none(i); 196d5ac70f0Sopenharmony_ci return -EINVAL; 197d5ac70f0Sopenharmony_ci } 198d5ac70f0Sopenharmony_ci return changed; 199d5ac70f0Sopenharmony_ci} 200d5ac70f0Sopenharmony_ci 201d5ac70f0Sopenharmony_ciint snd_interval_refine_first(snd_interval_t *i) 202d5ac70f0Sopenharmony_ci{ 203d5ac70f0Sopenharmony_ci const unsigned int last_max = i->max; 204d5ac70f0Sopenharmony_ci 205d5ac70f0Sopenharmony_ci if (snd_interval_empty(i)) 206d5ac70f0Sopenharmony_ci return -ENOENT; 207d5ac70f0Sopenharmony_ci if (snd_interval_single(i)) 208d5ac70f0Sopenharmony_ci return 0; 209d5ac70f0Sopenharmony_ci i->max = i->min; 210d5ac70f0Sopenharmony_ci if (i->openmin) 211d5ac70f0Sopenharmony_ci i->max++; 212d5ac70f0Sopenharmony_ci /* only exclude max value if also excluded before refine */ 213d5ac70f0Sopenharmony_ci i->openmax = (i->openmax && i->max >= last_max); 214d5ac70f0Sopenharmony_ci return 1; 215d5ac70f0Sopenharmony_ci} 216d5ac70f0Sopenharmony_ci 217d5ac70f0Sopenharmony_ciint snd_interval_refine_last(snd_interval_t *i) 218d5ac70f0Sopenharmony_ci{ 219d5ac70f0Sopenharmony_ci const unsigned int last_min = i->min; 220d5ac70f0Sopenharmony_ci 221d5ac70f0Sopenharmony_ci if (snd_interval_empty(i)) 222d5ac70f0Sopenharmony_ci return -ENOENT; 223d5ac70f0Sopenharmony_ci if (snd_interval_single(i)) 224d5ac70f0Sopenharmony_ci return 0; 225d5ac70f0Sopenharmony_ci i->min = i->max; 226d5ac70f0Sopenharmony_ci if (i->openmax) 227d5ac70f0Sopenharmony_ci i->min--; 228d5ac70f0Sopenharmony_ci /* only exclude min value if also excluded before refine */ 229d5ac70f0Sopenharmony_ci i->openmin = (i->openmin && i->min <= last_min); 230d5ac70f0Sopenharmony_ci return 1; 231d5ac70f0Sopenharmony_ci} 232d5ac70f0Sopenharmony_ci 233d5ac70f0Sopenharmony_ciint snd_interval_refine_set(snd_interval_t *i, unsigned int val) 234d5ac70f0Sopenharmony_ci{ 235d5ac70f0Sopenharmony_ci snd_interval_t t; 236d5ac70f0Sopenharmony_ci t.empty = 0; 237d5ac70f0Sopenharmony_ci t.min = t.max = val; 238d5ac70f0Sopenharmony_ci t.openmin = t.openmax = 0; 239d5ac70f0Sopenharmony_ci t.integer = 1; 240d5ac70f0Sopenharmony_ci return snd_interval_refine(i, &t); 241d5ac70f0Sopenharmony_ci} 242d5ac70f0Sopenharmony_ci 243d5ac70f0Sopenharmony_civoid snd_interval_add(const snd_interval_t *a, const snd_interval_t *b, snd_interval_t *c) 244d5ac70f0Sopenharmony_ci{ 245d5ac70f0Sopenharmony_ci if (a->empty || b->empty) { 246d5ac70f0Sopenharmony_ci snd_interval_none(c); 247d5ac70f0Sopenharmony_ci return; 248d5ac70f0Sopenharmony_ci } 249d5ac70f0Sopenharmony_ci c->empty = 0; 250d5ac70f0Sopenharmony_ci c->min = add(a->min, b->min); 251d5ac70f0Sopenharmony_ci c->openmin = (a->openmin || b->openmin); 252d5ac70f0Sopenharmony_ci c->max = add(a->max, b->max); 253d5ac70f0Sopenharmony_ci c->openmax = (a->openmax || b->openmax); 254d5ac70f0Sopenharmony_ci c->integer = (a->integer && b->integer); 255d5ac70f0Sopenharmony_ci} 256d5ac70f0Sopenharmony_ci 257d5ac70f0Sopenharmony_civoid snd_interval_sub(const snd_interval_t *a, const snd_interval_t *b, snd_interval_t *c) 258d5ac70f0Sopenharmony_ci{ 259d5ac70f0Sopenharmony_ci if (a->empty || b->empty) { 260d5ac70f0Sopenharmony_ci snd_interval_none(c); 261d5ac70f0Sopenharmony_ci return; 262d5ac70f0Sopenharmony_ci } 263d5ac70f0Sopenharmony_ci c->empty = 0; 264d5ac70f0Sopenharmony_ci c->min = sub(a->min, b->max); 265d5ac70f0Sopenharmony_ci c->openmin = (a->openmin || b->openmax); 266d5ac70f0Sopenharmony_ci c->max = add(a->max, b->min); 267d5ac70f0Sopenharmony_ci c->openmax = (a->openmax || b->openmin); 268d5ac70f0Sopenharmony_ci c->integer = (a->integer && b->integer); 269d5ac70f0Sopenharmony_ci} 270d5ac70f0Sopenharmony_ci 271d5ac70f0Sopenharmony_civoid snd_interval_mul(const snd_interval_t *a, const snd_interval_t *b, snd_interval_t *c) 272d5ac70f0Sopenharmony_ci{ 273d5ac70f0Sopenharmony_ci if (a->empty || b->empty) { 274d5ac70f0Sopenharmony_ci snd_interval_none(c); 275d5ac70f0Sopenharmony_ci return; 276d5ac70f0Sopenharmony_ci } 277d5ac70f0Sopenharmony_ci c->empty = 0; 278d5ac70f0Sopenharmony_ci c->min = mul(a->min, b->min); 279d5ac70f0Sopenharmony_ci c->openmin = (a->openmin || b->openmin); 280d5ac70f0Sopenharmony_ci c->max = mul(a->max, b->max); 281d5ac70f0Sopenharmony_ci c->openmax = (a->openmax || b->openmax); 282d5ac70f0Sopenharmony_ci c->integer = (a->integer && b->integer); 283d5ac70f0Sopenharmony_ci} 284d5ac70f0Sopenharmony_ci 285d5ac70f0Sopenharmony_civoid snd_interval_div(const snd_interval_t *a, const snd_interval_t *b, snd_interval_t *c) 286d5ac70f0Sopenharmony_ci{ 287d5ac70f0Sopenharmony_ci unsigned int r; 288d5ac70f0Sopenharmony_ci if (a->empty || b->empty) { 289d5ac70f0Sopenharmony_ci snd_interval_none(c); 290d5ac70f0Sopenharmony_ci return; 291d5ac70f0Sopenharmony_ci } 292d5ac70f0Sopenharmony_ci c->empty = 0; 293d5ac70f0Sopenharmony_ci c->min = div32(a->min, b->max, &r); 294d5ac70f0Sopenharmony_ci c->openmin = (r || a->openmin || b->openmax); 295d5ac70f0Sopenharmony_ci if (b->min > 0) { 296d5ac70f0Sopenharmony_ci c->max = div32(a->max, b->min, &r); 297d5ac70f0Sopenharmony_ci if (r) { 298d5ac70f0Sopenharmony_ci c->max++; 299d5ac70f0Sopenharmony_ci c->openmax = 1; 300d5ac70f0Sopenharmony_ci } else 301d5ac70f0Sopenharmony_ci c->openmax = (a->openmax || b->openmin); 302d5ac70f0Sopenharmony_ci } else { 303d5ac70f0Sopenharmony_ci c->max = UINT_MAX; 304d5ac70f0Sopenharmony_ci c->openmax = 0; 305d5ac70f0Sopenharmony_ci } 306d5ac70f0Sopenharmony_ci c->integer = 0; 307d5ac70f0Sopenharmony_ci} 308d5ac70f0Sopenharmony_ci 309d5ac70f0Sopenharmony_ci/* a * b / c */ 310d5ac70f0Sopenharmony_civoid snd_interval_muldiv(const snd_interval_t *a, const snd_interval_t *b, 311d5ac70f0Sopenharmony_ci const snd_interval_t *c, snd_interval_t *d) 312d5ac70f0Sopenharmony_ci{ 313d5ac70f0Sopenharmony_ci unsigned int r; 314d5ac70f0Sopenharmony_ci if (a->empty || b->empty || c->empty) { 315d5ac70f0Sopenharmony_ci snd_interval_none(d); 316d5ac70f0Sopenharmony_ci return; 317d5ac70f0Sopenharmony_ci } 318d5ac70f0Sopenharmony_ci d->empty = 0; 319d5ac70f0Sopenharmony_ci d->min = muldiv32(a->min, b->min, c->max, &r); 320d5ac70f0Sopenharmony_ci d->openmin = (r || a->openmin || b->openmin || c->openmax); 321d5ac70f0Sopenharmony_ci d->max = muldiv32(a->max, b->max, c->min, &r); 322d5ac70f0Sopenharmony_ci if (r) { 323d5ac70f0Sopenharmony_ci d->max++; 324d5ac70f0Sopenharmony_ci d->openmax = 1; 325d5ac70f0Sopenharmony_ci } else 326d5ac70f0Sopenharmony_ci d->openmax = (a->openmax || b->openmax || c->openmin); 327d5ac70f0Sopenharmony_ci d->integer = 0; 328d5ac70f0Sopenharmony_ci} 329d5ac70f0Sopenharmony_ci 330d5ac70f0Sopenharmony_ci/* a * b / k */ 331d5ac70f0Sopenharmony_civoid snd_interval_muldivk(const snd_interval_t *a, const snd_interval_t *b, 332d5ac70f0Sopenharmony_ci unsigned int k, snd_interval_t *c) 333d5ac70f0Sopenharmony_ci{ 334d5ac70f0Sopenharmony_ci unsigned int r; 335d5ac70f0Sopenharmony_ci if (a->empty || b->empty) { 336d5ac70f0Sopenharmony_ci snd_interval_none(c); 337d5ac70f0Sopenharmony_ci return; 338d5ac70f0Sopenharmony_ci } 339d5ac70f0Sopenharmony_ci c->empty = 0; 340d5ac70f0Sopenharmony_ci c->min = muldiv32(a->min, b->min, k, &r); 341d5ac70f0Sopenharmony_ci c->openmin = (r || a->openmin || b->openmin); 342d5ac70f0Sopenharmony_ci c->max = muldiv32(a->max, b->max, k, &r); 343d5ac70f0Sopenharmony_ci if (r) { 344d5ac70f0Sopenharmony_ci c->max++; 345d5ac70f0Sopenharmony_ci c->openmax = 1; 346d5ac70f0Sopenharmony_ci } else 347d5ac70f0Sopenharmony_ci c->openmax = (a->openmax || b->openmax); 348d5ac70f0Sopenharmony_ci c->integer = 0; 349d5ac70f0Sopenharmony_ci} 350d5ac70f0Sopenharmony_ci 351d5ac70f0Sopenharmony_ci/* a * k / b */ 352d5ac70f0Sopenharmony_civoid snd_interval_mulkdiv(const snd_interval_t *a, unsigned int k, 353d5ac70f0Sopenharmony_ci const snd_interval_t *b, snd_interval_t *c) 354d5ac70f0Sopenharmony_ci{ 355d5ac70f0Sopenharmony_ci unsigned int r; 356d5ac70f0Sopenharmony_ci if (a->empty || b->empty) { 357d5ac70f0Sopenharmony_ci snd_interval_none(c); 358d5ac70f0Sopenharmony_ci return; 359d5ac70f0Sopenharmony_ci } 360d5ac70f0Sopenharmony_ci c->empty = 0; 361d5ac70f0Sopenharmony_ci c->min = muldiv32(a->min, k, b->max, &r); 362d5ac70f0Sopenharmony_ci c->openmin = (r || a->openmin || b->openmax); 363d5ac70f0Sopenharmony_ci if (b->min > 0) { 364d5ac70f0Sopenharmony_ci c->max = muldiv32(a->max, k, b->min, &r); 365d5ac70f0Sopenharmony_ci if (r) { 366d5ac70f0Sopenharmony_ci c->max++; 367d5ac70f0Sopenharmony_ci c->openmax = 1; 368d5ac70f0Sopenharmony_ci } else 369d5ac70f0Sopenharmony_ci c->openmax = (a->openmax || b->openmin); 370d5ac70f0Sopenharmony_ci } else { 371d5ac70f0Sopenharmony_ci c->max = UINT_MAX; 372d5ac70f0Sopenharmony_ci c->openmax = 0; 373d5ac70f0Sopenharmony_ci } 374d5ac70f0Sopenharmony_ci c->integer = 0; 375d5ac70f0Sopenharmony_ci} 376d5ac70f0Sopenharmony_ci 377d5ac70f0Sopenharmony_civoid snd_interval_print(const snd_interval_t *i, snd_output_t *out) 378d5ac70f0Sopenharmony_ci{ 379d5ac70f0Sopenharmony_ci if (snd_interval_empty(i)) 380d5ac70f0Sopenharmony_ci snd_output_printf(out, "NONE"); 381d5ac70f0Sopenharmony_ci else if (i->min == 0 && i->openmin == 0 && 382d5ac70f0Sopenharmony_ci i->max == UINT_MAX && i->openmax == 0) 383d5ac70f0Sopenharmony_ci snd_output_printf(out, "ALL"); 384d5ac70f0Sopenharmony_ci else if (snd_interval_single(i) && i->integer) 385d5ac70f0Sopenharmony_ci snd_output_printf(out, "%u", snd_interval_value(i)); 386d5ac70f0Sopenharmony_ci else 387d5ac70f0Sopenharmony_ci snd_output_printf(out, "%c%u %u%c", 388d5ac70f0Sopenharmony_ci i->openmin ? '(' : '[', 389d5ac70f0Sopenharmony_ci i->min, i->max, 390d5ac70f0Sopenharmony_ci i->openmax ? ')' : ']'); 391d5ac70f0Sopenharmony_ci} 392d5ac70f0Sopenharmony_ci 393d5ac70f0Sopenharmony_ci#if 0 394d5ac70f0Sopenharmony_cistatic void boundary_abs(int a, int adir, int *b, int *bdir) 395d5ac70f0Sopenharmony_ci{ 396d5ac70f0Sopenharmony_ci if (a < 0 || (a == 0 && adir < 0)) { 397d5ac70f0Sopenharmony_ci *b = -a; 398d5ac70f0Sopenharmony_ci *bdir = -adir; 399d5ac70f0Sopenharmony_ci } else { 400d5ac70f0Sopenharmony_ci *b = a; 401d5ac70f0Sopenharmony_ci *bdir = adir; 402d5ac70f0Sopenharmony_ci } 403d5ac70f0Sopenharmony_ci} 404d5ac70f0Sopenharmony_ci#endif 405d5ac70f0Sopenharmony_ci 406d5ac70f0Sopenharmony_civoid boundary_sub(int a, int adir, int b, int bdir, int *c, int *cdir) 407d5ac70f0Sopenharmony_ci{ 408d5ac70f0Sopenharmony_ci adir = adir < 0 ? -1 : (adir > 0 ? 1 : 0); 409d5ac70f0Sopenharmony_ci bdir = bdir < 0 ? -1 : (bdir > 0 ? 1 : 0); 410d5ac70f0Sopenharmony_ci *c = a - b; 411d5ac70f0Sopenharmony_ci *cdir = adir - bdir; 412d5ac70f0Sopenharmony_ci if (*cdir == -2) { 413d5ac70f0Sopenharmony_ci assert(*c > INT_MIN); 414d5ac70f0Sopenharmony_ci (*c)--; 415d5ac70f0Sopenharmony_ci } else if (*cdir == 2) { 416d5ac70f0Sopenharmony_ci assert(*c < INT_MAX); 417d5ac70f0Sopenharmony_ci (*c)++; 418d5ac70f0Sopenharmony_ci } 419d5ac70f0Sopenharmony_ci} 420d5ac70f0Sopenharmony_ci 421d5ac70f0Sopenharmony_ciint boundary_lt(unsigned int a, int adir, unsigned int b, int bdir) 422d5ac70f0Sopenharmony_ci{ 423d5ac70f0Sopenharmony_ci assert(a > 0 || adir >= 0); 424d5ac70f0Sopenharmony_ci assert(b > 0 || bdir >= 0); 425d5ac70f0Sopenharmony_ci if (adir < 0) { 426d5ac70f0Sopenharmony_ci a--; 427d5ac70f0Sopenharmony_ci adir = 1; 428d5ac70f0Sopenharmony_ci } else if (adir > 0) 429d5ac70f0Sopenharmony_ci adir = 1; 430d5ac70f0Sopenharmony_ci if (bdir < 0) { 431d5ac70f0Sopenharmony_ci b--; 432d5ac70f0Sopenharmony_ci bdir = 1; 433d5ac70f0Sopenharmony_ci } else if (bdir > 0) 434d5ac70f0Sopenharmony_ci bdir = 1; 435d5ac70f0Sopenharmony_ci return a < b || (a == b && adir < bdir); 436d5ac70f0Sopenharmony_ci} 437d5ac70f0Sopenharmony_ci 438d5ac70f0Sopenharmony_ci/* Return 1 if min is nearer to best than max */ 439d5ac70f0Sopenharmony_ciint boundary_nearer(int min, int mindir, int best, int bestdir, int max, int maxdir) 440d5ac70f0Sopenharmony_ci{ 441d5ac70f0Sopenharmony_ci int dmin, dmindir; 442d5ac70f0Sopenharmony_ci int dmax, dmaxdir; 443d5ac70f0Sopenharmony_ci boundary_sub(best, bestdir, min, mindir, &dmin, &dmindir); 444d5ac70f0Sopenharmony_ci boundary_sub(max, maxdir, best, bestdir, &dmax, &dmaxdir); 445d5ac70f0Sopenharmony_ci return boundary_lt(dmin, dmindir, dmax, dmaxdir); 446d5ac70f0Sopenharmony_ci} 447d5ac70f0Sopenharmony_ci 448