/* * Copyright (c) 2019-2025 Allwinner Technology Co., Ltd. ALL rights reserved. * * Allwinner is a trademark of Allwinner Technology Co.,Ltd., registered in * the the people's Republic of China and other countries. * All Allwinner Technology Co.,Ltd. trademarks are used with permission. * * DISCLAIMER * THIRD PARTY LICENCES MAY BE REQUIRED TO IMPLEMENT THE SOLUTION/PRODUCT. * IF YOU NEED TO INTEGRATE THIRD PARTY’S TECHNOLOGY (SONY, DTS, DOLBY, AVS OR MPEGLA, ETC.) * IN ALLWINNERS’SDK OR PRODUCTS, YOU SHALL BE SOLELY RESPONSIBLE TO OBTAIN * ALL APPROPRIATELY REQUIRED THIRD PARTY LICENCES. * ALLWINNER SHALL HAVE NO WARRANTY, INDEMNITY OR OTHER OBLIGATIONS WITH RESPECT TO MATTERS * COVERED UNDER ANY REQUIRED THIRD PARTY LICENSE. * YOU ARE SOLELY RESPONSIBLE FOR YOUR USAGE OF THIRD PARTY’S TECHNOLOGY. * * * THIS SOFTWARE IS PROVIDED BY ALLWINNER"AS IS" AND TO THE MAXIMUM EXTENT * PERMITTED BY LAW, ALLWINNER EXPRESSLY DISCLAIMS ALL WARRANTIES OF ANY KIND, * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION REGARDING * THE TITLE, NON-INFRINGEMENT, ACCURACY, CONDITION, COMPLETENESS, PERFORMANCE * OR MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * IN NO EVENT SHALL ALLWINNER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS, OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef __SOUND_PCM_COMMON_H #define __SOUND_PCM_COMMON_H #include #include #ifndef EBADFD #define EBADFD 77 #endif #ifndef ESTRPIPE #define ESTRPIPE 86 #endif #ifndef LONG_MAX #define LONG_MAX ((long)(~0UL>>1)) #endif #ifndef ULONG_MAX #define ULONG_MAX (~0UL) #endif #ifndef UINT_MAX #define UINT_MAX (~0U) #endif #define SND_PCM_APPEND (1<<8) typedef unsigned long snd_pcm_uframes_t; typedef signed long snd_pcm_sframes_t; typedef union snd_interval snd_interval_t; #define SNDRV_PCM_INFO_MMAP 0x00000001 /* hardware supports mmap */ #define SNDRV_PCM_INFO_MMAP_VALID 0x00000002 /* period data are valid during transfer */ #define SNDRV_PCM_INFO_DOUBLE 0x00000004 /* Double buffering needed for PCM start/stop */ #define SNDRV_PCM_INFO_BATCH 0x00000010 /* double buffering */ #define SNDRV_PCM_INFO_INTERLEAVED 0x00000100 /* channels are interleaved */ #define SNDRV_PCM_INFO_NONINTERLEAVED 0x00000200 /* channels are not interleaved */ #define SNDRV_PCM_INFO_COMPLEX 0x00000400 /* complex frame organization (mmap only) */ #define SNDRV_PCM_INFO_BLOCK_TRANSFER 0x00010000 /* hardware transfer block of samples */ #define SNDRV_PCM_INFO_OVERRANGE 0x00020000 /* hardware supports ADC (capture) overrange detection */ #define SNDRV_PCM_INFO_RESUME 0x00040000 /* hardware supports stream resume after suspend */ #define SNDRV_PCM_INFO_PAUSE 0x00080000 /* pause ioctl is supported */ #define SNDRV_PCM_INFO_HALF_DUPLEX 0x00100000 /* only half duplex */ #define SNDRV_PCM_INFO_JOINT_DUPLEX 0x00200000 /* playback and capture stream are somewhat correlated */ #define SNDRV_PCM_INFO_SYNC_START 0x00400000 /* pcm support some kind of sync go */ #define SNDRV_PCM_INFO_NO_PERIOD_WAKEUP 0x00800000 /* period wakeup can be disabled */ #define SNDRV_PCM_INFO_HAS_WALL_CLOCK 0x01000000 /* (Deprecated)has audio wall clock for audio/system time sync */ #define SNDRV_PCM_INFO_HAS_LINK_ATIME 0x01000000 /* report hardware link audio time, reset on startup */ #define SNDRV_PCM_INFO_HAS_LINK_ABSOLUTE_ATIME 0x02000000 /* report absolute hardware link audio time, not reset on startup */ #define SNDRV_PCM_INFO_HAS_LINK_ESTIMATED_ATIME 0x04000000 /* report estimated link audio time */ #define SNDRV_PCM_INFO_HAS_LINK_SYNCHRONIZED_ATIME 0x08000000 /* report synchronized audio/system time */ #define SNDRV_PCM_INFO_DRAIN_TRIGGER 0x40000000 /* internal kernel flag - trigger in drain */ #define SNDRV_PCM_INFO_FIFO_IN_FRAMES 0x80000000 /* internal kernel flag - FIFO size is in frames */ /** PCM access type */ typedef enum _snd_pcm_access { /** mmap access with simple interleaved channels */ SND_PCM_ACCESS_MMAP_INTERLEAVED = 0, /** mmap access with simple non interleaved channels */ SND_PCM_ACCESS_MMAP_NONINTERLEAVED, /** mmap access with complex placement */ SND_PCM_ACCESS_MMAP_COMPLEX, /** snd_pcm_readi/snd_pcm_writei access */ SND_PCM_ACCESS_RW_INTERLEAVED, /** snd_pcm_readn/snd_pcm_writen access */ SND_PCM_ACCESS_RW_NONINTERLEAVED, SND_PCM_ACCESS_LAST = SND_PCM_ACCESS_RW_NONINTERLEAVED } snd_pcm_access_t; /** PCM sample format */ typedef enum _snd_pcm_format { /** Unknown */ SND_PCM_FORMAT_UNKNOWN = -1, /** Signed 8 bit */ SND_PCM_FORMAT_S8 = 0, /** Unsigned 8 bit */ SND_PCM_FORMAT_U8, /** Signed 16 bit Little Endian */ SND_PCM_FORMAT_S16_LE, /** Signed 16 bit Big Endian */ SND_PCM_FORMAT_S16_BE, /** Unsigned 16 bit Little Endian */ SND_PCM_FORMAT_U16_LE, /** Unsigned 16 bit Big Endian */ SND_PCM_FORMAT_U16_BE, /** Signed 24 bit Little Endian using low three bytes in 32-bit word */ SND_PCM_FORMAT_S24_LE, /** Signed 24 bit Big Endian using low three bytes in 32-bit word */ SND_PCM_FORMAT_S24_BE, /** Unsigned 24 bit Little Endian using low three bytes in 32-bit word */ SND_PCM_FORMAT_U24_LE, /** Unsigned 24 bit Big Endian using low three bytes in 32-bit word */ SND_PCM_FORMAT_U24_BE, /** Signed 32 bit Little Endian */ SND_PCM_FORMAT_S32_LE, /** Signed 32 bit Big Endian */ SND_PCM_FORMAT_S32_BE, /** Unsigned 32 bit Little Endian */ SND_PCM_FORMAT_U32_LE, /** Unsigned 32 bit Big Endian */ SND_PCM_FORMAT_U32_BE, /* only support little endian */ /** Signed 16 bit CPU endian */ SND_PCM_FORMAT_S16 = SND_PCM_FORMAT_S16_LE, /** Unsigned 16 bit CPU endian */ SND_PCM_FORMAT_U16 = SND_PCM_FORMAT_U16_LE, /** Signed 24 bit CPU endian */ SND_PCM_FORMAT_S24 = SND_PCM_FORMAT_S24_LE, /** Unsigned 24 bit CPU endian */ SND_PCM_FORMAT_U24 = SND_PCM_FORMAT_U24_LE, /** Signed 32 bit CPU endian */ SND_PCM_FORMAT_S32 = SND_PCM_FORMAT_S32_LE, /** Unsigned 32 bit CPU endian */ SND_PCM_FORMAT_U32 = SND_PCM_FORMAT_U32_LE, SND_PCM_FORMAT_LAST = SND_PCM_FORMAT_U32_BE, } snd_pcm_format_t; /** PCM state */ typedef enum _ksnd_pcm_state { /** Open */ SNDRV_PCM_STATE_OPEN = 0, /** Setup installed */ SNDRV_PCM_STATE_SETUP, /** Ready to start */ SNDRV_PCM_STATE_PREPARED, /** Running */ SNDRV_PCM_STATE_RUNNING, /** Stopped: underrun (playback) or overrun (capture) detected */ SNDRV_PCM_STATE_XRUN, /** Draining: running (playback) or stopped (capture) */ SNDRV_PCM_STATE_DRAINING, /** Paused */ SNDRV_PCM_STATE_PAUSED, /** Hardware is suspended */ SNDRV_PCM_STATE_SUSPENDED, /** Hardware is disconnected */ SNDRV_PCM_STATE_DISCONNECTED, SNDRV_PCM_STATE_LAST = SNDRV_PCM_STATE_DISCONNECTED } ksnd_pcm_state_t; typedef int snd_pcm_hw_param_t; #define SND_PCM_HW_PARAM_ACCESS 0 #define SND_PCM_HW_PARAM_FORMAT 1 #define SND_PCM_HW_PARAM_FIRST_MASK SND_PCM_HW_PARAM_ACCESS #define SND_PCM_HW_PARAM_LAST_MASK SND_PCM_HW_PARAM_FORMAT #define SND_PCM_HW_PARAM_SAMPLE_BITS 2 #define SND_PCM_HW_PARAM_FRAME_BITS 3 #define SND_PCM_HW_PARAM_CHANNELS 4 #define SND_PCM_HW_PARAM_RATE 5 #define SND_PCM_HW_PARAM_PERIOD_TIME 6 #define SND_PCM_HW_PARAM_PERIOD_SIZE 7 #define SND_PCM_HW_PARAM_PERIOD_BYTES 8 #define SND_PCM_HW_PARAM_PERIODS 9 #define SND_PCM_HW_PARAM_BUFFER_TIME 10 #define SND_PCM_HW_PARAM_BUFFER_SIZE 11 #define SND_PCM_HW_PARAM_BUFFER_BYTES 12 #define SND_PCM_HW_PARAM_FIRST_RANGE SND_PCM_HW_PARAM_SAMPLE_BITS #define SND_PCM_HW_PARAM_LAST_RANGE SND_PCM_HW_PARAM_BUFFER_BYTES #define SND_PCM_HW_PARAM_FIRST_INTERVAL SND_PCM_HW_PARAM_ACCESS #define SND_PCM_HW_PARAM_LAST_INTERVAL SND_PCM_HW_PARAM_BUFFER_BYTES static inline int hw_is_mask(int var) { return var >= SND_PCM_HW_PARAM_FIRST_MASK && var <= SND_PCM_HW_PARAM_LAST_MASK; } static inline int hw_is_range(int var) { return var >= SND_PCM_HW_PARAM_FIRST_RANGE && var <= SND_PCM_HW_PARAM_LAST_RANGE; } union snd_interval { struct { uint32_t min; uint32_t max; int openmin; /* whether the interval is left-open */ int openmax; /* whether the interval is right-open */ int integer; /* whether the value is integer or not */ int empty; } range; uint32_t mask; }; typedef struct snd_pcm_hw_params { union snd_interval intervals[SND_PCM_HW_PARAM_LAST_INTERVAL - SND_PCM_HW_PARAM_FIRST_INTERVAL + 1]; unsigned int can_paused; uint32_t rmask; /* W: requested masks */ uint32_t cmask; /* R: changed masks */ } snd_pcm_hw_params_t; typedef struct snd_pcm_sw_params { snd_pcm_uframes_t avail_min; /* min avail frames for wakeup */ snd_pcm_uframes_t start_threshold; /* min hw_avail frames for automatic start */ snd_pcm_uframes_t stop_threshold; /* min avail frames for automatic stop */ snd_pcm_uframes_t silence_size; /* silence block size */ snd_pcm_uframes_t boundary; /* pointers wrap point */ } snd_pcm_sw_params_t; typedef long ksnd_pcm_sframes_t; typedef unsigned long ksnd_pcm_uframes_t; struct snd_pcm_mmap_status { ksnd_pcm_state_t state; ksnd_pcm_uframes_t hw_ptr; }; struct snd_pcm_mmap_control { ksnd_pcm_uframes_t appl_ptr; ksnd_pcm_uframes_t avail_min; }; #define SNDRV_PCM_SYNC_PTR_HWSYNC (1<<0) /* execute hwsync */ #define SNDRV_PCM_SYNC_PTR_APPL (1<<1) /* get appl_ptr from driver (r/w op) */ #define SNDRV_PCM_SYNC_PTR_AVAIL_MIN (1<<2) /* get avail_min from driver */ typedef struct _snd_pcm_channel_info { unsigned int channel; void *addr; /* base address of channel samples */ unsigned int first; /* offset to first sample in bits */ unsigned int step; /* samples distance in bits */ enum { SND_PCM_AREA_MMAP, SND_PCM_AREA_LOCAL } type; } snd_pcm_channel_info_t; static inline unsigned int div32(unsigned int a, unsigned int b, unsigned int *r) { if (b == 0) { *r = 0; return UINT_MAX; } *r = a % b; return a / b; } static inline uint64_t div_u64_rem(uint64_t dividend, uint32_t divisor, uint32_t *remainder) { *remainder = dividend % divisor; return dividend / divisor; } static inline unsigned int div_down(unsigned int a, unsigned int b) { if (b == 0) return UINT_MAX; return a / b; } static inline unsigned int div_up(unsigned int a, unsigned int b) { unsigned int r; unsigned int q; if (b == 0) return UINT_MAX; q = div32(a, b, &r); if (r) ++q; return q; } static inline unsigned int mul(unsigned int a, unsigned int b) { if (a == 0) return 0; if (div_down(UINT_MAX, a) < b) return UINT_MAX; return a * b; } static inline unsigned int add(unsigned int a, unsigned int b) { if (a >= UINT_MAX - b) return UINT_MAX; return a + b; } static inline unsigned int sub(unsigned int a, unsigned int b) { if (a > b) return a - b; return 0; } static inline unsigned int muldiv32(unsigned int a, unsigned int b, unsigned int c, unsigned int *r) { uint64_t n = (uint64_t)a * (uint64_t)b; uint32_t rem; if (c == 0) { *r = 0; return UINT_MAX; } n = div_u64_rem(n, c, &rem); if (n >= UINT_MAX) { *r = 0; return UINT_MAX; } *r = rem; return n; } static inline int __pcm_ffs(uint32_t value) { uint32_t offset; for (offset = 0; offset < sizeof(value)*8; offset++) { if (value & (1< 0; offset--) { if (value & (1<<(offset - 1))) return offset; } return -1; } static inline snd_pcm_access_t params_access(const struct snd_pcm_hw_params *p) { const union snd_interval *interval = NULL; interval = &p->intervals[SND_PCM_HW_PARAM_ACCESS - SND_PCM_HW_PARAM_FIRST_INTERVAL]; if (interval->mask != 0) return (snd_pcm_access_t)__ffs(interval->mask); return (snd_pcm_access_t)-1; } static inline snd_pcm_format_t params_format(const struct snd_pcm_hw_params *p) { const union snd_interval *interval = NULL; interval = &p->intervals[SND_PCM_HW_PARAM_FORMAT - SND_PCM_HW_PARAM_FIRST_INTERVAL]; if (interval->mask != 0) return (snd_pcm_format_t)__ffs(interval->mask); return SND_PCM_FORMAT_UNKNOWN; } static inline snd_interval_t *hw_param_interval(struct snd_pcm_hw_params *params, snd_pcm_hw_param_t var) { return ¶ms->intervals[var]; } static inline const union snd_interval *hw_param_interval_c(const struct snd_pcm_hw_params *params, int var) { return ¶ms->intervals[var - SND_PCM_HW_PARAM_FIRST_INTERVAL]; } static inline unsigned int params_channels(const struct snd_pcm_hw_params *p) { return hw_param_interval_c(p, SND_PCM_HW_PARAM_CHANNELS)->range.min; } static inline unsigned int params_rate(const struct snd_pcm_hw_params *p) { return hw_param_interval_c(p, SND_PCM_HW_PARAM_RATE)->range.min; } static inline unsigned int params_period_size(const struct snd_pcm_hw_params *p) { return hw_param_interval_c(p, SND_PCM_HW_PARAM_PERIOD_SIZE)->range.min; } static inline unsigned int params_period_time(const struct snd_pcm_hw_params *p) { return hw_param_interval_c(p, SND_PCM_HW_PARAM_PERIOD_TIME)->range.min; } static inline unsigned int params_periods(const struct snd_pcm_hw_params *p) { return hw_param_interval_c(p, SND_PCM_HW_PARAM_PERIODS)->range.min; } static inline unsigned int params_buffer_size(const struct snd_pcm_hw_params *p) { return hw_param_interval_c(p, SND_PCM_HW_PARAM_BUFFER_SIZE)->range.min; } static inline unsigned int params_buffer_time(const struct snd_pcm_hw_params *p) { return hw_param_interval_c(p, SND_PCM_HW_PARAM_BUFFER_TIME)->range.min; } int snd_pcm_format_physical_width(snd_pcm_format_t format); #define SND_MASK_BITS 32 static inline void snd_mask_none(snd_interval_t *interval) { interval->mask = 0U; } static inline void snd_mask_any(snd_interval_t *interval) { interval->mask = ~0U; } static inline int snd_mask_empty(const snd_interval_t *interval) { return !interval->mask; } static inline int snd_mask_full(const snd_interval_t *interval) { return interval->mask == 0xffffffff; } static inline unsigned int snd_mask_min(const snd_interval_t *interval) { unsigned int i; for (i = 0; i < sizeof(interval->mask) * 8; i++) { if (interval->mask & (1 << i)) return i; } return 0; } static inline unsigned int snd_mask_max(const snd_interval_t *interval) { unsigned int i; for (i = sizeof(interval->mask) * 8; i > 0; i--) { if (interval->mask & (1 << (i - 1))) return i - 1; } return 0; } static inline void snd_mask_set(snd_interval_t *interval, unsigned int val) { interval->mask |= (1 << val); } static inline void snd_mask_reset(snd_interval_t *interval, unsigned int val) { interval->mask &= ~(1 << val); } static inline void snd_mask_set_range(snd_interval_t *interval, unsigned int from, unsigned int to) { unsigned int i; for (i = from; i <= to; i++) interval->mask |= (1 << i); } static inline void snd_mask_reset_range(snd_interval_t *interval, unsigned int from, unsigned int to) { unsigned int i; for (i = from; i <= to; i++) interval->mask &= ~(1 << i); } static inline void snd_mask_leave(snd_interval_t *interval, unsigned int val) { snd_mask_none(interval); interval->mask |= (1 << val); } static inline void snd_mask_intersect(snd_interval_t *interval, const snd_interval_t *v) { interval->mask &= v->mask; } static inline int snd_mask_eq(snd_interval_t *interval, const snd_interval_t *v) { return interval->mask == v->mask; } static inline void snd_mask_copy(snd_interval_t *interval, const snd_interval_t *v) { interval->mask = v->mask; } static inline int snd_mask_test(const snd_interval_t *interval, unsigned int val) { return interval->mask & (1 << val); } static inline int snd_mask_single(const snd_interval_t *interval) { unsigned int bits = sizeof(interval->mask) * 8; unsigned int i; int c = 0; for (i = 0; i < bits; ++i) { if (!(interval->mask & (1 << i))) continue; if (c) return 0; c++; } return 1; } static inline int snd_mask_refine(snd_interval_t *interval, const snd_interval_t *v) { snd_interval_t old; snd_mask_copy(&old, interval); snd_mask_intersect(interval, v); if (snd_mask_empty(interval)) return -EINVAL; return !snd_mask_eq(interval, &old); } static inline int snd_mask_refine_first(snd_interval_t *interval) { if (snd_mask_single(interval)) return 0; snd_mask_leave(interval, snd_mask_min(interval)); return 1; } static inline int snd_mask_refine_last(snd_interval_t *interval) { if (snd_mask_single(interval)) return 0; snd_mask_leave(interval, snd_mask_max(interval)); return 1; } static inline int snd_mask_refine_min(snd_interval_t *interval, unsigned int val) { if (snd_mask_min(interval) >= val) return 0; snd_mask_reset_range(interval, 0, val - 1); if (snd_mask_empty(interval)) return -EINVAL; return 1; } static inline int snd_mask_refine_max(snd_interval_t *interval, unsigned int val) { if (snd_mask_max(interval) <= val) return 0; snd_mask_reset_range(interval, val + 1, SND_MASK_BITS); if (snd_mask_empty(interval)) return -EINVAL; return 1; } static inline int snd_mask_refine_set(snd_interval_t *interval, unsigned int val) { int changed; changed = !snd_mask_single(interval); snd_mask_leave(interval, val); if (snd_mask_empty(interval)) return -EINVAL; return changed; } static inline int snd_mask_value(const snd_interval_t *interval) { return snd_mask_min(interval); } static inline int snd_mask_always_eq(const snd_interval_t *m1, const snd_interval_t *m2) { return snd_mask_single(m1) && snd_mask_single(m2) && snd_mask_value(m1) == snd_mask_value(m2); } static inline int snd_mask_never_eq(const snd_interval_t *m1, const snd_interval_t *m2) { if (m1->mask & m2->mask) return 0; return 1; } static inline void snd_range_any(snd_interval_t *i) { i->range.min = 0; i->range.openmin = 0; i->range.max = UINT_MAX; i->range.openmax= 0; i->range.integer = 0; i->range.empty = 0; } static inline void snd_range_none(snd_interval_t *i) { i->range.empty = 1; } static inline int snd_range_checkempty(snd_interval_t *i) { return (i->range.min > i->range.max || (i->range.min == i->range.max && (i->range.openmin || i->range.openmax))); } static inline int snd_range_empty(const snd_interval_t *i) { return i->range.empty; } static inline int snd_range_single(const snd_interval_t *i) { return (i->range.min == i->range.max || (i->range.min + 1 == i->range.max && i->range.openmax)); } static inline int snd_range_value(const snd_interval_t *i) { return i->range.min; } static inline void snd_range_set_value(snd_interval_t *i, unsigned int val) { i->range.openmax = i->range.openmin = 0; i->range.min = i->range.max = val; i->range.integer = 0; i->range.empty = 0; } static inline int snd_range_min(const snd_interval_t *i) { return i->range.min; } static inline int snd_range_max(const snd_interval_t *i) { unsigned int v; v = i->range.max; if (i->range.openmax) v--; return v; } static inline void snd_range_set_minmax(snd_interval_t *i, unsigned int min, unsigned int max) { i->range.openmax = i->range.openmin = 0; i->range.min = min; i->range.max = max; i->range.integer = 0; i->range.empty = 0; } static inline int snd_range_test(const snd_interval_t *i, unsigned int val) { return !((i->range.min > val || (i->range.min == val && i->range.openmin) || i->range.max < val || (i->range.max == val && i->range.openmax))); } static inline void snd_range_copy(snd_interval_t *d, const snd_interval_t *s) { d->range = s->range; } static inline int snd_range_setinteger(snd_interval_t *i) { if (i->range.integer) return 0; if (i->range.openmin && i->range.openmax && i->range.min == i->range.max) return -EINVAL; i->range.integer = 1; return 1; } static inline void snd_range_floor(snd_interval_t *i) { if (i->range.integer || snd_range_empty(i)) return; i->range.openmin = 0; if (i->range.openmax) { i->range.max--; i->range.openmax = 0; } i->range.integer = 1; } static inline void snd_range_unfloor(snd_interval_t *i) { if (snd_range_empty(i)) return; if (i->range.max == UINT_MAX) return; if (i->range.openmax) return; i->range.max++; i->range.openmax = 1; i->range.integer = 0; } static inline int snd_range_eq(const snd_interval_t *i1, const snd_interval_t *i2) { if (i1->range.empty) return i2->range.empty; if (i2->range.empty) return i1->range.empty; return i1->range.min == i2->range.min && i1->range.openmin == i2->range.openmin && i1->range.max == i2->range.max && i1->range.openmax == i2->range.openmax; } static inline int snd_range_always_eq(const snd_interval_t *i1, const snd_interval_t *i2) { return snd_range_single(i1) && snd_range_single(i2) && snd_range_value(i1) == snd_range_value(i2); } static inline int snd_range_never_eq(const snd_interval_t *i1, const snd_interval_t *i2) { return (i1->range.max < i2->range.min || (i1->range.max == i2->range.min && (i1->range.openmax || i1->range.openmin)) || i1->range.min > i2->range.max || (i1->range.min == i2->range.max && (i1->range.openmin || i2->range.openmax))); } int snd_range_refine(snd_interval_t *i, const snd_interval_t *v); int snd_range_refine_first(snd_interval_t *i); int snd_range_refine_last(snd_interval_t *i); int snd_range_refine_min(snd_interval_t *i, unsigned int min, int openmin); int snd_range_refine_max(snd_interval_t *i, unsigned int max, int openmax); int snd_range_refine_set(snd_interval_t *i, unsigned int val); void snd_range_add(const snd_interval_t *a, const snd_interval_t *b, snd_interval_t *c); void snd_range_sub(const snd_interval_t *a, const snd_interval_t *b, snd_interval_t *c); void snd_range_mul(const snd_interval_t *a, const snd_interval_t *b, snd_interval_t *c); void snd_range_div(const snd_interval_t *a, const snd_interval_t *b, snd_interval_t *c); void snd_range_muldiv(const snd_interval_t *a, const snd_interval_t *b, const snd_interval_t *c, snd_interval_t *d); void snd_range_muldivk(const snd_interval_t *a, const snd_interval_t *b, unsigned int k, snd_interval_t *c); void snd_range_mulkdiv(const snd_interval_t *a, unsigned int k, const snd_interval_t *b, snd_interval_t *c); int snd_range_list(snd_interval_t *i, unsigned int count, const unsigned int *list, unsigned int mask); const char *snd_pcm_hw_param_name(snd_pcm_hw_param_t param); struct snd_pcm_hw_rule; typedef int (*snd_pcm_hw_rule_func_t)(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule); struct snd_pcm_hw_rule { unsigned int cond; int var; int deps[4]; snd_pcm_hw_rule_func_t func; void *private_data; }; int snd_pcm_hw_rule_mul(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule); int snd_pcm_hw_rule_div(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule); int snd_pcm_hw_rule_muldivk(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule); int snd_pcm_hw_rule_mulkdiv(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule); int snd_pcm_hw_rule_format(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule); int snd_pcm_hw_rule_sample_bits(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule); int snd_pcm_hw_rule_rate(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule); int snd_pcm_hw_rule_buffer_bytes_max(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule); #endif /* __SOUND_PCM_COMMON_H */