pcm_common.h 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813
  1. /*
  2. * Copyright (c) 2019-2025 Allwinner Technology Co., Ltd. ALL rights reserved.
  3. *
  4. * Allwinner is a trademark of Allwinner Technology Co.,Ltd., registered in
  5. * the the people's Republic of China and other countries.
  6. * All Allwinner Technology Co.,Ltd. trademarks are used with permission.
  7. *
  8. * DISCLAIMER
  9. * THIRD PARTY LICENCES MAY BE REQUIRED TO IMPLEMENT THE SOLUTION/PRODUCT.
  10. * IF YOU NEED TO INTEGRATE THIRD PARTY’S TECHNOLOGY (SONY, DTS, DOLBY, AVS OR MPEGLA, ETC.)
  11. * IN ALLWINNERS’SDK OR PRODUCTS, YOU SHALL BE SOLELY RESPONSIBLE TO OBTAIN
  12. * ALL APPROPRIATELY REQUIRED THIRD PARTY LICENCES.
  13. * ALLWINNER SHALL HAVE NO WARRANTY, INDEMNITY OR OTHER OBLIGATIONS WITH RESPECT TO MATTERS
  14. * COVERED UNDER ANY REQUIRED THIRD PARTY LICENSE.
  15. * YOU ARE SOLELY RESPONSIBLE FOR YOUR USAGE OF THIRD PARTY’S TECHNOLOGY.
  16. *
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY ALLWINNER"AS IS" AND TO THE MAXIMUM EXTENT
  19. * PERMITTED BY LAW, ALLWINNER EXPRESSLY DISCLAIMS ALL WARRANTIES OF ANY KIND,
  20. * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION REGARDING
  21. * THE TITLE, NON-INFRINGEMENT, ACCURACY, CONDITION, COMPLETENESS, PERFORMANCE
  22. * OR MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  23. * IN NO EVENT SHALL ALLWINNER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  24. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  25. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  26. * LOSS OF USE, DATA, OR PROFITS, OR BUSINESS INTERRUPTION)
  27. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  28. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  29. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  30. * OF THE POSSIBILITY OF SUCH DAMAGE.
  31. */
  32. #ifndef __SOUND_PCM_COMMON_H
  33. #define __SOUND_PCM_COMMON_H
  34. #include <stdint.h>
  35. #include <errno.h>
  36. #ifndef EBADFD
  37. #define EBADFD 77
  38. #endif
  39. #ifndef ESTRPIPE
  40. #define ESTRPIPE 86
  41. #endif
  42. #ifndef LONG_MAX
  43. #define LONG_MAX ((long)(~0UL>>1))
  44. #endif
  45. #ifndef ULONG_MAX
  46. #define ULONG_MAX (~0UL)
  47. #endif
  48. #ifndef UINT_MAX
  49. #define UINT_MAX (~0U)
  50. #endif
  51. #define SND_PCM_APPEND (1<<8)
  52. typedef unsigned long snd_pcm_uframes_t;
  53. typedef signed long snd_pcm_sframes_t;
  54. typedef union snd_interval snd_interval_t;
  55. #define SNDRV_PCM_INFO_MMAP 0x00000001 /* hardware supports mmap */
  56. #define SNDRV_PCM_INFO_MMAP_VALID 0x00000002 /* period data are valid during transfer */
  57. #define SNDRV_PCM_INFO_DOUBLE 0x00000004 /* Double buffering needed for PCM start/stop */
  58. #define SNDRV_PCM_INFO_BATCH 0x00000010 /* double buffering */
  59. #define SNDRV_PCM_INFO_INTERLEAVED 0x00000100 /* channels are interleaved */
  60. #define SNDRV_PCM_INFO_NONINTERLEAVED 0x00000200 /* channels are not interleaved */
  61. #define SNDRV_PCM_INFO_COMPLEX 0x00000400 /* complex frame organization (mmap only) */
  62. #define SNDRV_PCM_INFO_BLOCK_TRANSFER 0x00010000 /* hardware transfer block of samples */
  63. #define SNDRV_PCM_INFO_OVERRANGE 0x00020000 /* hardware supports ADC (capture) overrange detection */
  64. #define SNDRV_PCM_INFO_RESUME 0x00040000 /* hardware supports stream resume after suspend */
  65. #define SNDRV_PCM_INFO_PAUSE 0x00080000 /* pause ioctl is supported */
  66. #define SNDRV_PCM_INFO_HALF_DUPLEX 0x00100000 /* only half duplex */
  67. #define SNDRV_PCM_INFO_JOINT_DUPLEX 0x00200000 /* playback and capture stream are somewhat correlated */
  68. #define SNDRV_PCM_INFO_SYNC_START 0x00400000 /* pcm support some kind of sync go */
  69. #define SNDRV_PCM_INFO_NO_PERIOD_WAKEUP 0x00800000 /* period wakeup can be disabled */
  70. #define SNDRV_PCM_INFO_HAS_WALL_CLOCK 0x01000000 /* (Deprecated)has audio wall clock for audio/system time sync */
  71. #define SNDRV_PCM_INFO_HAS_LINK_ATIME 0x01000000 /* report hardware link audio time, reset on startup */
  72. #define SNDRV_PCM_INFO_HAS_LINK_ABSOLUTE_ATIME 0x02000000 /* report absolute hardware link audio time, not reset on startup */
  73. #define SNDRV_PCM_INFO_HAS_LINK_ESTIMATED_ATIME 0x04000000 /* report estimated link audio time */
  74. #define SNDRV_PCM_INFO_HAS_LINK_SYNCHRONIZED_ATIME 0x08000000 /* report synchronized audio/system time */
  75. #define SNDRV_PCM_INFO_DRAIN_TRIGGER 0x40000000 /* internal kernel flag - trigger in drain */
  76. #define SNDRV_PCM_INFO_FIFO_IN_FRAMES 0x80000000 /* internal kernel flag - FIFO size is in frames */
  77. /** PCM access type */
  78. typedef enum _snd_pcm_access {
  79. /** mmap access with simple interleaved channels */
  80. SND_PCM_ACCESS_MMAP_INTERLEAVED = 0,
  81. /** mmap access with simple non interleaved channels */
  82. SND_PCM_ACCESS_MMAP_NONINTERLEAVED,
  83. /** mmap access with complex placement */
  84. SND_PCM_ACCESS_MMAP_COMPLEX,
  85. /** snd_pcm_readi/snd_pcm_writei access */
  86. SND_PCM_ACCESS_RW_INTERLEAVED,
  87. /** snd_pcm_readn/snd_pcm_writen access */
  88. SND_PCM_ACCESS_RW_NONINTERLEAVED,
  89. SND_PCM_ACCESS_LAST = SND_PCM_ACCESS_RW_NONINTERLEAVED
  90. } snd_pcm_access_t;
  91. /** PCM sample format */
  92. typedef enum _snd_pcm_format {
  93. /** Unknown */
  94. SND_PCM_FORMAT_UNKNOWN = -1,
  95. /** Signed 8 bit */
  96. SND_PCM_FORMAT_S8 = 0,
  97. /** Unsigned 8 bit */
  98. SND_PCM_FORMAT_U8,
  99. /** Signed 16 bit Little Endian */
  100. SND_PCM_FORMAT_S16_LE,
  101. /** Signed 16 bit Big Endian */
  102. SND_PCM_FORMAT_S16_BE,
  103. /** Unsigned 16 bit Little Endian */
  104. SND_PCM_FORMAT_U16_LE,
  105. /** Unsigned 16 bit Big Endian */
  106. SND_PCM_FORMAT_U16_BE,
  107. /** Signed 24 bit Little Endian using low three bytes in 32-bit word */
  108. SND_PCM_FORMAT_S24_LE,
  109. /** Signed 24 bit Big Endian using low three bytes in 32-bit word */
  110. SND_PCM_FORMAT_S24_BE,
  111. /** Unsigned 24 bit Little Endian using low three bytes in 32-bit word */
  112. SND_PCM_FORMAT_U24_LE,
  113. /** Unsigned 24 bit Big Endian using low three bytes in 32-bit word */
  114. SND_PCM_FORMAT_U24_BE,
  115. /** Signed 32 bit Little Endian */
  116. SND_PCM_FORMAT_S32_LE,
  117. /** Signed 32 bit Big Endian */
  118. SND_PCM_FORMAT_S32_BE,
  119. /** Unsigned 32 bit Little Endian */
  120. SND_PCM_FORMAT_U32_LE,
  121. /** Unsigned 32 bit Big Endian */
  122. SND_PCM_FORMAT_U32_BE,
  123. /* only support little endian */
  124. /** Signed 16 bit CPU endian */
  125. SND_PCM_FORMAT_S16 = SND_PCM_FORMAT_S16_LE,
  126. /** Unsigned 16 bit CPU endian */
  127. SND_PCM_FORMAT_U16 = SND_PCM_FORMAT_U16_LE,
  128. /** Signed 24 bit CPU endian */
  129. SND_PCM_FORMAT_S24 = SND_PCM_FORMAT_S24_LE,
  130. /** Unsigned 24 bit CPU endian */
  131. SND_PCM_FORMAT_U24 = SND_PCM_FORMAT_U24_LE,
  132. /** Signed 32 bit CPU endian */
  133. SND_PCM_FORMAT_S32 = SND_PCM_FORMAT_S32_LE,
  134. /** Unsigned 32 bit CPU endian */
  135. SND_PCM_FORMAT_U32 = SND_PCM_FORMAT_U32_LE,
  136. SND_PCM_FORMAT_LAST = SND_PCM_FORMAT_U32_BE,
  137. } snd_pcm_format_t;
  138. /** PCM state */
  139. typedef enum _ksnd_pcm_state {
  140. /** Open */
  141. SNDRV_PCM_STATE_OPEN = 0,
  142. /** Setup installed */
  143. SNDRV_PCM_STATE_SETUP,
  144. /** Ready to start */
  145. SNDRV_PCM_STATE_PREPARED,
  146. /** Running */
  147. SNDRV_PCM_STATE_RUNNING,
  148. /** Stopped: underrun (playback) or overrun (capture) detected */
  149. SNDRV_PCM_STATE_XRUN,
  150. /** Draining: running (playback) or stopped (capture) */
  151. SNDRV_PCM_STATE_DRAINING,
  152. /** Paused */
  153. SNDRV_PCM_STATE_PAUSED,
  154. /** Hardware is suspended */
  155. SNDRV_PCM_STATE_SUSPENDED,
  156. /** Hardware is disconnected */
  157. SNDRV_PCM_STATE_DISCONNECTED,
  158. SNDRV_PCM_STATE_LAST = SNDRV_PCM_STATE_DISCONNECTED
  159. } ksnd_pcm_state_t;
  160. typedef int snd_pcm_hw_param_t;
  161. #define SND_PCM_HW_PARAM_ACCESS 0
  162. #define SND_PCM_HW_PARAM_FORMAT 1
  163. #define SND_PCM_HW_PARAM_FIRST_MASK SND_PCM_HW_PARAM_ACCESS
  164. #define SND_PCM_HW_PARAM_LAST_MASK SND_PCM_HW_PARAM_FORMAT
  165. #define SND_PCM_HW_PARAM_SAMPLE_BITS 2
  166. #define SND_PCM_HW_PARAM_FRAME_BITS 3
  167. #define SND_PCM_HW_PARAM_CHANNELS 4
  168. #define SND_PCM_HW_PARAM_RATE 5
  169. #define SND_PCM_HW_PARAM_PERIOD_TIME 6
  170. #define SND_PCM_HW_PARAM_PERIOD_SIZE 7
  171. #define SND_PCM_HW_PARAM_PERIOD_BYTES 8
  172. #define SND_PCM_HW_PARAM_PERIODS 9
  173. #define SND_PCM_HW_PARAM_BUFFER_TIME 10
  174. #define SND_PCM_HW_PARAM_BUFFER_SIZE 11
  175. #define SND_PCM_HW_PARAM_BUFFER_BYTES 12
  176. #define SND_PCM_HW_PARAM_FIRST_RANGE SND_PCM_HW_PARAM_SAMPLE_BITS
  177. #define SND_PCM_HW_PARAM_LAST_RANGE SND_PCM_HW_PARAM_BUFFER_BYTES
  178. #define SND_PCM_HW_PARAM_FIRST_INTERVAL SND_PCM_HW_PARAM_ACCESS
  179. #define SND_PCM_HW_PARAM_LAST_INTERVAL SND_PCM_HW_PARAM_BUFFER_BYTES
  180. static inline int hw_is_mask(int var)
  181. {
  182. return var >= SND_PCM_HW_PARAM_FIRST_MASK &&
  183. var <= SND_PCM_HW_PARAM_LAST_MASK;
  184. }
  185. static inline int hw_is_range(int var)
  186. {
  187. return var >= SND_PCM_HW_PARAM_FIRST_RANGE &&
  188. var <= SND_PCM_HW_PARAM_LAST_RANGE;
  189. }
  190. union snd_interval {
  191. struct {
  192. uint32_t min;
  193. uint32_t max;
  194. int openmin; /* whether the interval is left-open */
  195. int openmax; /* whether the interval is right-open */
  196. int integer; /* whether the value is integer or not */
  197. int empty;
  198. } range;
  199. uint32_t mask;
  200. };
  201. typedef struct snd_pcm_hw_params {
  202. union snd_interval intervals[SND_PCM_HW_PARAM_LAST_INTERVAL -
  203. SND_PCM_HW_PARAM_FIRST_INTERVAL + 1];
  204. unsigned int can_paused;
  205. uint32_t rmask; /* W: requested masks */
  206. uint32_t cmask; /* R: changed masks */
  207. } snd_pcm_hw_params_t;
  208. typedef struct snd_pcm_sw_params {
  209. snd_pcm_uframes_t avail_min; /* min avail frames for wakeup */
  210. snd_pcm_uframes_t start_threshold; /* min hw_avail frames for automatic start */
  211. snd_pcm_uframes_t stop_threshold; /* min avail frames for automatic stop */
  212. snd_pcm_uframes_t silence_size; /* silence block size */
  213. snd_pcm_uframes_t boundary; /* pointers wrap point */
  214. } snd_pcm_sw_params_t;
  215. typedef long ksnd_pcm_sframes_t;
  216. typedef unsigned long ksnd_pcm_uframes_t;
  217. struct snd_pcm_mmap_status {
  218. ksnd_pcm_state_t state;
  219. ksnd_pcm_uframes_t hw_ptr;
  220. };
  221. struct snd_pcm_mmap_control {
  222. ksnd_pcm_uframes_t appl_ptr;
  223. ksnd_pcm_uframes_t avail_min;
  224. };
  225. #define SNDRV_PCM_SYNC_PTR_HWSYNC (1<<0) /* execute hwsync */
  226. #define SNDRV_PCM_SYNC_PTR_APPL (1<<1) /* get appl_ptr from driver (r/w op) */
  227. #define SNDRV_PCM_SYNC_PTR_AVAIL_MIN (1<<2) /* get avail_min from driver */
  228. typedef struct _snd_pcm_channel_info {
  229. unsigned int channel;
  230. void *addr; /* base address of channel samples */
  231. unsigned int first; /* offset to first sample in bits */
  232. unsigned int step; /* samples distance in bits */
  233. enum { SND_PCM_AREA_MMAP, SND_PCM_AREA_LOCAL } type;
  234. } snd_pcm_channel_info_t;
  235. static inline unsigned int div32(unsigned int a, unsigned int b,
  236. unsigned int *r)
  237. {
  238. if (b == 0) {
  239. *r = 0;
  240. return UINT_MAX;
  241. }
  242. *r = a % b;
  243. return a / b;
  244. }
  245. static inline uint64_t div_u64_rem(uint64_t dividend, uint32_t divisor, uint32_t *remainder)
  246. {
  247. *remainder = dividend % divisor;
  248. return dividend / divisor;
  249. }
  250. static inline unsigned int div_down(unsigned int a, unsigned int b)
  251. {
  252. if (b == 0)
  253. return UINT_MAX;
  254. return a / b;
  255. }
  256. static inline unsigned int div_up(unsigned int a, unsigned int b)
  257. {
  258. unsigned int r;
  259. unsigned int q;
  260. if (b == 0)
  261. return UINT_MAX;
  262. q = div32(a, b, &r);
  263. if (r)
  264. ++q;
  265. return q;
  266. }
  267. static inline unsigned int mul(unsigned int a, unsigned int b)
  268. {
  269. if (a == 0)
  270. return 0;
  271. if (div_down(UINT_MAX, a) < b)
  272. return UINT_MAX;
  273. return a * b;
  274. }
  275. static inline unsigned int add(unsigned int a, unsigned int b)
  276. {
  277. if (a >= UINT_MAX - b)
  278. return UINT_MAX;
  279. return a + b;
  280. }
  281. static inline unsigned int sub(unsigned int a, unsigned int b)
  282. {
  283. if (a > b)
  284. return a - b;
  285. return 0;
  286. }
  287. static inline unsigned int muldiv32(unsigned int a, unsigned int b,
  288. unsigned int c, unsigned int *r)
  289. {
  290. uint64_t n = (uint64_t)a * (uint64_t)b;
  291. uint32_t rem;
  292. if (c == 0) {
  293. *r = 0;
  294. return UINT_MAX;
  295. }
  296. n = div_u64_rem(n, c, &rem);
  297. if (n >= UINT_MAX) {
  298. *r = 0;
  299. return UINT_MAX;
  300. }
  301. *r = rem;
  302. return n;
  303. }
  304. static inline int __pcm_ffs(uint32_t value)
  305. {
  306. uint32_t offset;
  307. for (offset = 0; offset < sizeof(value)*8; offset++) {
  308. if (value & (1<<offset))
  309. return offset;
  310. }
  311. return -1;
  312. }
  313. static inline int __ffs(uint32_t value)
  314. {
  315. uint32_t offset;
  316. for (offset = 0; offset < sizeof(value)*8; offset++) {
  317. if (value & (1<<offset))
  318. return offset;
  319. }
  320. return -1;
  321. }
  322. static inline int __fls(uint32_t value)
  323. {
  324. uint32_t offset;
  325. for (offset = sizeof(value)*8; offset > 0; offset--) {
  326. if (value & (1<<(offset - 1)))
  327. return offset;
  328. }
  329. return -1;
  330. }
  331. static inline snd_pcm_access_t params_access(const struct snd_pcm_hw_params *p)
  332. {
  333. const union snd_interval *interval = NULL;
  334. interval = &p->intervals[SND_PCM_HW_PARAM_ACCESS -
  335. SND_PCM_HW_PARAM_FIRST_INTERVAL];
  336. if (interval->mask != 0)
  337. return (snd_pcm_access_t)__ffs(interval->mask);
  338. return (snd_pcm_access_t)-1;
  339. }
  340. static inline snd_pcm_format_t params_format(const struct snd_pcm_hw_params *p)
  341. {
  342. const union snd_interval *interval = NULL;
  343. interval = &p->intervals[SND_PCM_HW_PARAM_FORMAT -
  344. SND_PCM_HW_PARAM_FIRST_INTERVAL];
  345. if (interval->mask != 0)
  346. return (snd_pcm_format_t)__ffs(interval->mask);
  347. return SND_PCM_FORMAT_UNKNOWN;
  348. }
  349. static inline snd_interval_t *hw_param_interval(struct snd_pcm_hw_params *params,
  350. snd_pcm_hw_param_t var)
  351. {
  352. return &params->intervals[var];
  353. }
  354. static inline const union snd_interval *hw_param_interval_c(const struct snd_pcm_hw_params *params,
  355. int var)
  356. {
  357. return &params->intervals[var - SND_PCM_HW_PARAM_FIRST_INTERVAL];
  358. }
  359. static inline unsigned int params_channels(const struct snd_pcm_hw_params *p)
  360. {
  361. return hw_param_interval_c(p, SND_PCM_HW_PARAM_CHANNELS)->range.min;
  362. }
  363. static inline unsigned int params_rate(const struct snd_pcm_hw_params *p)
  364. {
  365. return hw_param_interval_c(p, SND_PCM_HW_PARAM_RATE)->range.min;
  366. }
  367. static inline unsigned int params_period_size(const struct snd_pcm_hw_params *p)
  368. {
  369. return hw_param_interval_c(p, SND_PCM_HW_PARAM_PERIOD_SIZE)->range.min;
  370. }
  371. static inline unsigned int params_period_time(const struct snd_pcm_hw_params *p)
  372. {
  373. return hw_param_interval_c(p, SND_PCM_HW_PARAM_PERIOD_TIME)->range.min;
  374. }
  375. static inline unsigned int params_periods(const struct snd_pcm_hw_params *p)
  376. {
  377. return hw_param_interval_c(p, SND_PCM_HW_PARAM_PERIODS)->range.min;
  378. }
  379. static inline unsigned int params_buffer_size(const struct snd_pcm_hw_params *p)
  380. {
  381. return hw_param_interval_c(p, SND_PCM_HW_PARAM_BUFFER_SIZE)->range.min;
  382. }
  383. static inline unsigned int params_buffer_time(const struct snd_pcm_hw_params *p)
  384. {
  385. return hw_param_interval_c(p, SND_PCM_HW_PARAM_BUFFER_TIME)->range.min;
  386. }
  387. int snd_pcm_format_physical_width(snd_pcm_format_t format);
  388. #define SND_MASK_BITS 32
  389. static inline void snd_mask_none(snd_interval_t *interval)
  390. {
  391. interval->mask = 0U;
  392. }
  393. static inline void snd_mask_any(snd_interval_t *interval)
  394. {
  395. interval->mask = ~0U;
  396. }
  397. static inline int snd_mask_empty(const snd_interval_t *interval)
  398. {
  399. return !interval->mask;
  400. }
  401. static inline int snd_mask_full(const snd_interval_t *interval)
  402. {
  403. return interval->mask == 0xffffffff;
  404. }
  405. static inline unsigned int snd_mask_min(const snd_interval_t *interval)
  406. {
  407. unsigned int i;
  408. for (i = 0; i < sizeof(interval->mask) * 8; i++) {
  409. if (interval->mask & (1 << i))
  410. return i;
  411. }
  412. return 0;
  413. }
  414. static inline unsigned int snd_mask_max(const snd_interval_t *interval)
  415. {
  416. unsigned int i;
  417. for (i = sizeof(interval->mask) * 8; i > 0; i--) {
  418. if (interval->mask & (1 << (i - 1)))
  419. return i - 1;
  420. }
  421. return 0;
  422. }
  423. static inline void snd_mask_set(snd_interval_t *interval, unsigned int val)
  424. {
  425. interval->mask |= (1 << val);
  426. }
  427. static inline void snd_mask_reset(snd_interval_t *interval, unsigned int val)
  428. {
  429. interval->mask &= ~(1 << val);
  430. }
  431. static inline void snd_mask_set_range(snd_interval_t *interval,
  432. unsigned int from, unsigned int to)
  433. {
  434. unsigned int i;
  435. for (i = from; i <= to; i++)
  436. interval->mask |= (1 << i);
  437. }
  438. static inline void snd_mask_reset_range(snd_interval_t *interval,
  439. unsigned int from, unsigned int to)
  440. {
  441. unsigned int i;
  442. for (i = from; i <= to; i++)
  443. interval->mask &= ~(1 << i);
  444. }
  445. static inline void snd_mask_leave(snd_interval_t *interval, unsigned int val)
  446. {
  447. snd_mask_none(interval);
  448. interval->mask |= (1 << val);
  449. }
  450. static inline void snd_mask_intersect(snd_interval_t *interval, const snd_interval_t *v)
  451. {
  452. interval->mask &= v->mask;
  453. }
  454. static inline int snd_mask_eq(snd_interval_t *interval, const snd_interval_t *v)
  455. {
  456. return interval->mask == v->mask;
  457. }
  458. static inline void snd_mask_copy(snd_interval_t *interval, const snd_interval_t *v)
  459. {
  460. interval->mask = v->mask;
  461. }
  462. static inline int snd_mask_test(const snd_interval_t *interval, unsigned int val)
  463. {
  464. return interval->mask & (1 << val);
  465. }
  466. static inline int snd_mask_single(const snd_interval_t *interval)
  467. {
  468. unsigned int bits = sizeof(interval->mask) * 8;
  469. unsigned int i;
  470. int c = 0;
  471. for (i = 0; i < bits; ++i) {
  472. if (!(interval->mask & (1 << i)))
  473. continue;
  474. if (c)
  475. return 0;
  476. c++;
  477. }
  478. return 1;
  479. }
  480. static inline int snd_mask_refine(snd_interval_t *interval, const snd_interval_t *v)
  481. {
  482. snd_interval_t old;
  483. snd_mask_copy(&old, interval);
  484. snd_mask_intersect(interval, v);
  485. if (snd_mask_empty(interval))
  486. return -EINVAL;
  487. return !snd_mask_eq(interval, &old);
  488. }
  489. static inline int snd_mask_refine_first(snd_interval_t *interval)
  490. {
  491. if (snd_mask_single(interval))
  492. return 0;
  493. snd_mask_leave(interval, snd_mask_min(interval));
  494. return 1;
  495. }
  496. static inline int snd_mask_refine_last(snd_interval_t *interval)
  497. {
  498. if (snd_mask_single(interval))
  499. return 0;
  500. snd_mask_leave(interval, snd_mask_max(interval));
  501. return 1;
  502. }
  503. static inline int snd_mask_refine_min(snd_interval_t *interval, unsigned int val)
  504. {
  505. if (snd_mask_min(interval) >= val)
  506. return 0;
  507. snd_mask_reset_range(interval, 0, val - 1);
  508. if (snd_mask_empty(interval))
  509. return -EINVAL;
  510. return 1;
  511. }
  512. static inline int snd_mask_refine_max(snd_interval_t *interval, unsigned int val)
  513. {
  514. if (snd_mask_max(interval) <= val)
  515. return 0;
  516. snd_mask_reset_range(interval, val + 1, SND_MASK_BITS);
  517. if (snd_mask_empty(interval))
  518. return -EINVAL;
  519. return 1;
  520. }
  521. static inline int snd_mask_refine_set(snd_interval_t *interval, unsigned int val)
  522. {
  523. int changed;
  524. changed = !snd_mask_single(interval);
  525. snd_mask_leave(interval, val);
  526. if (snd_mask_empty(interval))
  527. return -EINVAL;
  528. return changed;
  529. }
  530. static inline int snd_mask_value(const snd_interval_t *interval)
  531. {
  532. return snd_mask_min(interval);
  533. }
  534. static inline int snd_mask_always_eq(const snd_interval_t *m1, const snd_interval_t *m2)
  535. {
  536. return snd_mask_single(m1) && snd_mask_single(m2) &&
  537. snd_mask_value(m1) == snd_mask_value(m2);
  538. }
  539. static inline int snd_mask_never_eq(const snd_interval_t *m1, const snd_interval_t *m2)
  540. {
  541. if (m1->mask & m2->mask)
  542. return 0;
  543. return 1;
  544. }
  545. static inline void snd_range_any(snd_interval_t *i)
  546. {
  547. i->range.min = 0;
  548. i->range.openmin = 0;
  549. i->range.max = UINT_MAX;
  550. i->range.openmax= 0;
  551. i->range.integer = 0;
  552. i->range.empty = 0;
  553. }
  554. static inline void snd_range_none(snd_interval_t *i)
  555. {
  556. i->range.empty = 1;
  557. }
  558. static inline int snd_range_checkempty(snd_interval_t *i)
  559. {
  560. return (i->range.min > i->range.max ||
  561. (i->range.min == i->range.max && (i->range.openmin || i->range.openmax)));
  562. }
  563. static inline int snd_range_empty(const snd_interval_t *i)
  564. {
  565. return i->range.empty;
  566. }
  567. static inline int snd_range_single(const snd_interval_t *i)
  568. {
  569. return (i->range.min == i->range.max ||
  570. (i->range.min + 1 == i->range.max && i->range.openmax));
  571. }
  572. static inline int snd_range_value(const snd_interval_t *i)
  573. {
  574. return i->range.min;
  575. }
  576. static inline void snd_range_set_value(snd_interval_t *i, unsigned int val)
  577. {
  578. i->range.openmax = i->range.openmin = 0;
  579. i->range.min = i->range.max = val;
  580. i->range.integer = 0;
  581. i->range.empty = 0;
  582. }
  583. static inline int snd_range_min(const snd_interval_t *i)
  584. {
  585. return i->range.min;
  586. }
  587. static inline int snd_range_max(const snd_interval_t *i)
  588. {
  589. unsigned int v;
  590. v = i->range.max;
  591. if (i->range.openmax)
  592. v--;
  593. return v;
  594. }
  595. static inline void snd_range_set_minmax(snd_interval_t *i, unsigned int min, unsigned int max)
  596. {
  597. i->range.openmax = i->range.openmin = 0;
  598. i->range.min = min;
  599. i->range.max = max;
  600. i->range.integer = 0;
  601. i->range.empty = 0;
  602. }
  603. static inline int snd_range_test(const snd_interval_t *i, unsigned int val)
  604. {
  605. return !((i->range.min > val || (i->range.min == val && i->range.openmin) ||
  606. i->range.max < val || (i->range.max == val && i->range.openmax)));
  607. }
  608. static inline void snd_range_copy(snd_interval_t *d, const snd_interval_t *s)
  609. {
  610. d->range = s->range;
  611. }
  612. static inline int snd_range_setinteger(snd_interval_t *i)
  613. {
  614. if (i->range.integer)
  615. return 0;
  616. if (i->range.openmin && i->range.openmax && i->range.min == i->range.max)
  617. return -EINVAL;
  618. i->range.integer = 1;
  619. return 1;
  620. }
  621. static inline void snd_range_floor(snd_interval_t *i)
  622. {
  623. if (i->range.integer || snd_range_empty(i))
  624. return;
  625. i->range.openmin = 0;
  626. if (i->range.openmax) {
  627. i->range.max--;
  628. i->range.openmax = 0;
  629. }
  630. i->range.integer = 1;
  631. }
  632. static inline void snd_range_unfloor(snd_interval_t *i)
  633. {
  634. if (snd_range_empty(i))
  635. return;
  636. if (i->range.max == UINT_MAX)
  637. return;
  638. if (i->range.openmax)
  639. return;
  640. i->range.max++;
  641. i->range.openmax = 1;
  642. i->range.integer = 0;
  643. }
  644. static inline int snd_range_eq(const snd_interval_t *i1, const snd_interval_t *i2)
  645. {
  646. if (i1->range.empty)
  647. return i2->range.empty;
  648. if (i2->range.empty)
  649. return i1->range.empty;
  650. return i1->range.min == i2->range.min &&
  651. i1->range.openmin == i2->range.openmin &&
  652. i1->range.max == i2->range.max &&
  653. i1->range.openmax == i2->range.openmax;
  654. }
  655. static inline int snd_range_always_eq(const snd_interval_t *i1, const snd_interval_t *i2)
  656. {
  657. return snd_range_single(i1) && snd_range_single(i2) &&
  658. snd_range_value(i1) == snd_range_value(i2);
  659. }
  660. static inline int snd_range_never_eq(const snd_interval_t *i1, const snd_interval_t *i2)
  661. {
  662. return (i1->range.max < i2->range.min ||
  663. (i1->range.max == i2->range.min &&
  664. (i1->range.openmax || i1->range.openmin)) ||
  665. i1->range.min > i2->range.max ||
  666. (i1->range.min == i2->range.max &&
  667. (i1->range.openmin || i2->range.openmax)));
  668. }
  669. int snd_range_refine(snd_interval_t *i, const snd_interval_t *v);
  670. int snd_range_refine_first(snd_interval_t *i);
  671. int snd_range_refine_last(snd_interval_t *i);
  672. int snd_range_refine_min(snd_interval_t *i, unsigned int min, int openmin);
  673. int snd_range_refine_max(snd_interval_t *i, unsigned int max, int openmax);
  674. int snd_range_refine_set(snd_interval_t *i, unsigned int val);
  675. void snd_range_add(const snd_interval_t *a, const snd_interval_t *b, snd_interval_t *c);
  676. void snd_range_sub(const snd_interval_t *a, const snd_interval_t *b, snd_interval_t *c);
  677. void snd_range_mul(const snd_interval_t *a, const snd_interval_t *b, snd_interval_t *c);
  678. void snd_range_div(const snd_interval_t *a, const snd_interval_t *b, snd_interval_t *c);
  679. void snd_range_muldiv(const snd_interval_t *a, const snd_interval_t *b,
  680. const snd_interval_t *c, snd_interval_t *d);
  681. void snd_range_muldivk(const snd_interval_t *a, const snd_interval_t *b,
  682. unsigned int k, snd_interval_t *c);
  683. void snd_range_mulkdiv(const snd_interval_t *a, unsigned int k,
  684. const snd_interval_t *b, snd_interval_t *c);
  685. int snd_range_list(snd_interval_t *i, unsigned int count,
  686. const unsigned int *list, unsigned int mask);
  687. const char *snd_pcm_hw_param_name(snd_pcm_hw_param_t param);
  688. struct snd_pcm_hw_rule;
  689. typedef int (*snd_pcm_hw_rule_func_t)(struct snd_pcm_hw_params *params,
  690. struct snd_pcm_hw_rule *rule);
  691. struct snd_pcm_hw_rule {
  692. unsigned int cond;
  693. int var;
  694. int deps[4];
  695. snd_pcm_hw_rule_func_t func;
  696. void *private_data;
  697. };
  698. int snd_pcm_hw_rule_mul(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule);
  699. int snd_pcm_hw_rule_div(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule);
  700. int snd_pcm_hw_rule_muldivk(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule);
  701. int snd_pcm_hw_rule_mulkdiv(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule);
  702. int snd_pcm_hw_rule_format(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule);
  703. int snd_pcm_hw_rule_sample_bits(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule);
  704. int snd_pcm_hw_rule_rate(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule);
  705. int snd_pcm_hw_rule_buffer_bytes_max(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule);
  706. #endif /* __SOUND_PCM_COMMON_H */