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 __AW_ALSA_PCM_LOCAL_H
33 #define __AW_ALSA_PCM_LOCAL_H
34 #ifdef __cplusplus
35 extern "C" {
36 #endif
37
38 #include <stdint.h>
39 #include <assert.h>
40 #include <pthread.h>
41 #include <errno.h>
42 #include <limits.h>
43 #include <aw-alsa-lib/pcm.h>
44 #include <aw-alsa-lib/pcm_config.h>
45
46 #define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
47
48 #define SND_PCM_VERSION "V1.7.3"
49
50 #define SND_PCM_RATE_FIX_PERIOD_SIZE
51
52 #if 0
53 #define REFINE_DEBUG
54 #endif
55
56 typedef enum _snd_set_mode {
57 SND_CHANGE,
58 SND_TRY,
59 SND_TEST,
60 } snd_set_mode_t;
61
62 typedef struct _snd_pcm_rbptr {
63 snd_pcm_t *master;
64 volatile snd_pcm_uframes_t *ptr;
65 //int fd;
66 off_t offset;
67 int link_dst_count;
68 snd_pcm_t **link_dst;
69 //void *private_data;
70 //void (*changed)(snd_pcm_t *pcm, snd_pcm_t *src);
71 } snd_pcm_rbptr_t;
72
73 typedef struct {
74 int (*close)(snd_pcm_t *pcm);
75 //int (*nonblock)(snd_pcm_t *pcm, int nonblock);
76 //int (*async)(snd_pcm_t *pcm, int sig, pid_t pid);
77 //int (*info)(snd_pcm_t *pcm, snd_pcm_info_t *info);
78 int (*hw_refine)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
79 int (*hw_params)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
80 int (*hw_free)(snd_pcm_t *pcm);
81 int (*sw_params)(snd_pcm_t *pcm, snd_pcm_sw_params_t *params); /* always locked */
82 int (*channel_info)(snd_pcm_t *pcm, snd_pcm_channel_info_t *info);
83 void (*dump)(snd_pcm_t *pcm);
84 int (*mmap)(snd_pcm_t *pcm);
85 int (*munmap)(snd_pcm_t *pcm);
86 snd_pcm_chmap_query_t **(*query_chmaps)(snd_pcm_t *pcm);
87 snd_pcm_chmap_t *(*get_chmap)(snd_pcm_t *pcm);
88 int (*set_chmap)(snd_pcm_t *pcm, const snd_pcm_chmap_t *map);
89 } snd_pcm_ops_t;
90
91 typedef struct {
92 //int (*status)(snd_pcm_t *pcm, snd_pcm_status_t *status);
93 int (*prepare)(snd_pcm_t *pcm);
94 int (*reset)(snd_pcm_t *pcm);
95 int (*start)(snd_pcm_t *pcm);
96 int (*drop)(snd_pcm_t *pcm);
97 int (*drain)(snd_pcm_t *pcm);
98 int (*pause)(snd_pcm_t *pcm, int enable);
99 snd_pcm_state_t (*state)(snd_pcm_t *pcm);
100 int (*hwsync)(snd_pcm_t *pcm);
101 int (*delay)(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp);
102 int (*resume)(snd_pcm_t *pcm);
103 int (*link)(snd_pcm_t *pcm1, snd_pcm_t *pcm2);
104 //int (*link_slaves)(snd_pcm_t *pcm, snd_pcm_t *master);
105 int (*unlink)(snd_pcm_t *pcm);
106 //snd_pcm_sframes_t (*rewindable)(snd_pcm_t *pcm);
107 snd_pcm_sframes_t (*rewind)(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
108 //snd_pcm_sframes_t (*forwardable)(snd_pcm_t *pcm);
109 //snd_pcm_sframes_t (*forward)(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
110 snd_pcm_sframes_t (*writei)(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size);
111 //snd_pcm_sframes_t (*writen)(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size);
112 snd_pcm_sframes_t (*readi)(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size);
113 //snd_pcm_sframes_t (*readn)(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size);
114 snd_pcm_sframes_t (*avail_update)(snd_pcm_t *pcm);
115 snd_pcm_sframes_t (*mmap_commit)(snd_pcm_t *pcm, snd_pcm_uframes_t offset, snd_pcm_uframes_t size);
116 //int (*htimestamp)(snd_pcm_t *pcm, snd_pcm_uframes_t *avail, snd_htimestamp_t *tstamp);
117 //int (*poll_descriptors_count)(snd_pcm_t *pcm);
118 //int (*poll_descriptors)(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int space);
119 //int (*poll_revents)(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int nfds, unsigned short *revents);
120 int (*may_wait_for_avail_min)(snd_pcm_t *pcm, snd_pcm_uframes_t avail);
121 int (*wait)(snd_pcm_t *pcm, int timeout);
122 void (*cache_update)(snd_pcm_t *pcm, snd_pcm_uframes_t offset, snd_pcm_uframes_t size);
123 } snd_pcm_fast_ops_t;
124
125 struct _snd_pcm {
126 char *name;
127 snd_pcm_type_t type;
128 snd_pcm_stream_t stream;
129 int mode;
130 void *private_data;
131
132 int setup;
133 int donot_close; /* don't close this PCM */
134
135 snd_pcm_access_t access;
136 snd_pcm_format_t format;
137 unsigned int channels;
138 unsigned int rate;
139 snd_pcm_uframes_t period_size;
140 unsigned int period_time;
141 unsigned int periods;
142 snd_pcm_uframes_t avail_min;
143 snd_pcm_uframes_t start_threshold;
144 snd_pcm_uframes_t stop_threshold;
145 snd_pcm_uframes_t silence_size;
146 snd_pcm_uframes_t boundary;
147
148 snd_pcm_uframes_t buffer_size;
149 unsigned int buffer_time;
150 unsigned int sample_bits;
151 unsigned int frame_bits;
152
153 snd_pcm_rbptr_t appl;
154 snd_pcm_rbptr_t hw;
155
156 unsigned int mmap_rw; /* use always mmapped buffer */
157 unsigned int mmap_shadow; /* don't call actual mmap, use the mmaped buffer of the slave */
158 snd_pcm_channel_info_t *mmap_channels;
159 snd_pcm_channel_area_t *running_areas;
160 snd_pcm_channel_area_t *stopped_areas;
161
162 const snd_pcm_ops_t *ops;
163 const snd_pcm_fast_ops_t *fast_ops;
164 snd_pcm_t *op_arg;
165 snd_pcm_t *fast_op_arg;
166
167 pthread_mutex_t lock;
168 };
169
170 int snd_pcm_new(snd_pcm_t **pcmp, snd_pcm_type_t type, const char *name, snd_pcm_stream_t stream, int mode);
171 int snd_pcm_free(snd_pcm_t *pcm);
172
173 int snd_pcm_wait_nocheck(snd_pcm_t *pcm, int timeout);
174
175 void snd_pcm_areas_from_buf(snd_pcm_t *pcm, snd_pcm_channel_area_t *areas, void *buf);
176 void snd_pcm_areas_from_bufs(snd_pcm_t *pcm, snd_pcm_channel_area_t *areas, void **bufs);
177
178 int snd_pcm_mmap(snd_pcm_t *pcm);
179 int snd_pcm_munmap(snd_pcm_t *pcm);
180 void snd_pcm_set_hw_ptr(snd_pcm_t *pcm, volatile snd_pcm_uframes_t *hw_ptr, int fd, off_t offset);
181 void snd_pcm_set_appl_ptr(snd_pcm_t *pcm, volatile snd_pcm_uframes_t *appl_ptr, int fd, off_t offset);
182 void snd_pcm_link_hw_ptr(snd_pcm_t *pcm, snd_pcm_t *slave);
183 void snd_pcm_link_appl_ptr(snd_pcm_t *pcm, snd_pcm_t *slave);
184 void snd_pcm_unlink_hw_ptr(snd_pcm_t *pcm, snd_pcm_t *slave);
185 void snd_pcm_unlink_appl_ptr(snd_pcm_t *pcm, snd_pcm_t *slave);
186 void snd_pcm_mmap_appl_backward(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
187 void snd_pcm_mmap_appl_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
188 void snd_pcm_mmap_hw_backward(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
189 void snd_pcm_mmap_hw_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
190
191 typedef snd_pcm_sframes_t (*snd_pcm_xfer_areas_func_t)(snd_pcm_t *pcm,
192 const snd_pcm_channel_area_t *areas,
193 snd_pcm_uframes_t offset,
194 snd_pcm_uframes_t size);
195
196 snd_pcm_sframes_t snd_pcm_read_areas(snd_pcm_t *pcm, const snd_pcm_channel_area_t *areas,
197 snd_pcm_uframes_t offset, snd_pcm_uframes_t size,
198 snd_pcm_xfer_areas_func_t func);
199 snd_pcm_sframes_t snd_pcm_write_areas(snd_pcm_t *pcm, const snd_pcm_channel_area_t *areas,
200 snd_pcm_uframes_t offset, snd_pcm_uframes_t size,
201 snd_pcm_xfer_areas_func_t func);
snd_pcm_channel_info(snd_pcm_t * pcm,snd_pcm_channel_info_t * info)202 static inline int snd_pcm_channel_info(snd_pcm_t *pcm, snd_pcm_channel_info_t *info)
203 {
204 return pcm->ops->channel_info(pcm, info);
205 }
206 int snd_pcm_channel_info_shm(snd_pcm_t *pcm, snd_pcm_channel_info_t *info, int shmid);
207
208 /* return true if the PCM stream may wait to get avail_min space */
snd_pcm_may_wait_for_avail_min(snd_pcm_t * pcm,snd_pcm_uframes_t avail)209 static inline int snd_pcm_may_wait_for_avail_min(snd_pcm_t *pcm, snd_pcm_uframes_t avail)
210 {
211 if (avail >= pcm->avail_min)
212 return 0;
213 if (pcm->fast_ops->may_wait_for_avail_min)
214 return pcm->fast_ops->may_wait_for_avail_min(pcm, avail);
215 return 1;
216 }
217
snd_pcm_lock(snd_pcm_t * pcm)218 static inline void snd_pcm_lock(snd_pcm_t *pcm)
219 {
220 pthread_mutex_lock(&pcm->lock);
221 }
222
snd_pcm_unlock(snd_pcm_t * pcm)223 static inline void snd_pcm_unlock(snd_pcm_t *pcm)
224 {
225 pthread_mutex_unlock(&pcm->lock);
226 }
227
228
229 /* locked versions */
230 int __snd_pcm_mmap_begin(snd_pcm_t *pcm, const snd_pcm_channel_area_t **areas,
231 snd_pcm_uframes_t *offset, snd_pcm_uframes_t *frames);
232 snd_pcm_sframes_t __snd_pcm_mmap_commit(snd_pcm_t *pcm,
233 snd_pcm_uframes_t offset,
234 snd_pcm_uframes_t frames);
235 int __snd_pcm_wait_in_lock(snd_pcm_t *pcm, int timeout);
236
__snd_pcm_avail_update(snd_pcm_t * pcm)237 static inline snd_pcm_sframes_t __snd_pcm_avail_update(snd_pcm_t *pcm)
238 {
239 return pcm->fast_ops->avail_update(pcm->fast_op_arg);
240 }
241
__snd_pcm_start(snd_pcm_t * pcm)242 static inline int __snd_pcm_start(snd_pcm_t *pcm)
243 {
244 return pcm->fast_ops->start(pcm->fast_op_arg);
245 }
246
__snd_pcm_state(snd_pcm_t * pcm)247 static inline snd_pcm_state_t __snd_pcm_state(snd_pcm_t *pcm)
248 {
249 return pcm->fast_ops->state(pcm->fast_op_arg);
250 }
251
__snd_pcm_hwsync(snd_pcm_t * pcm)252 static inline int __snd_pcm_hwsync(snd_pcm_t *pcm)
253 {
254 return pcm->fast_ops->hwsync(pcm->fast_op_arg);
255 }
256
257 /* handle special error cases */
snd_pcm_check_error(snd_pcm_t * pcm,int err)258 static inline int snd_pcm_check_error(snd_pcm_t *pcm, int err)
259 {
260 if (err == -EINTR) {
261 switch (__snd_pcm_state(pcm)) {
262 case SND_PCM_STATE_XRUN:
263 return -EPIPE;
264 case SND_PCM_STATE_SUSPENDED:
265 return -ESTRPIPE;
266 case SND_PCM_STATE_DISCONNECTED:
267 return -ENODEV;
268 default:
269 break;
270 }
271 }
272 return err;
273 }
274
snd_pcm_mmap_playback_avail(snd_pcm_t * pcm)275 static inline snd_pcm_uframes_t snd_pcm_mmap_playback_avail(snd_pcm_t *pcm)
276 {
277 snd_pcm_sframes_t avail;
278 avail = *pcm->hw.ptr + pcm->buffer_size - *pcm->appl.ptr;
279 if (avail < 0)
280 avail += pcm->boundary;
281 else if ((snd_pcm_uframes_t) avail >= pcm->boundary)
282 avail -= pcm->boundary;
283 return avail;
284 }
285
snd_pcm_mmap_capture_avail(snd_pcm_t * pcm)286 static inline snd_pcm_uframes_t snd_pcm_mmap_capture_avail(snd_pcm_t *pcm)
287 {
288 snd_pcm_sframes_t avail;
289 avail = *pcm->hw.ptr - *pcm->appl.ptr;
290 if (avail < 0)
291 avail += pcm->boundary;
292 return avail;
293 }
294
snd_pcm_mmap_avail(snd_pcm_t * pcm)295 static inline snd_pcm_uframes_t snd_pcm_mmap_avail(snd_pcm_t *pcm)
296 {
297 if (pcm->stream == SND_PCM_STREAM_PLAYBACK)
298 return snd_pcm_mmap_playback_avail(pcm);
299 else
300 return snd_pcm_mmap_capture_avail(pcm);
301 }
302
snd_pcm_mmap_playback_hw_avail(snd_pcm_t * pcm)303 static inline snd_pcm_sframes_t snd_pcm_mmap_playback_hw_avail(snd_pcm_t *pcm)
304 {
305 return pcm->buffer_size - snd_pcm_mmap_playback_avail(pcm);
306 }
307
snd_pcm_mmap_capture_hw_avail(snd_pcm_t * pcm)308 static inline snd_pcm_sframes_t snd_pcm_mmap_capture_hw_avail(snd_pcm_t *pcm)
309 {
310 return pcm->buffer_size - snd_pcm_mmap_capture_avail(pcm);
311 }
312
snd_pcm_mmap_areas(snd_pcm_t * pcm)313 static inline const snd_pcm_channel_area_t *snd_pcm_mmap_areas(snd_pcm_t *pcm)
314 {
315 if (pcm->stopped_areas && __snd_pcm_state(pcm) != SND_PCM_STATE_RUNNING)
316 return pcm->stopped_areas;
317 return pcm->running_areas;
318 }
319
snd_pcm_mmap_offset(snd_pcm_t * pcm)320 static inline snd_pcm_uframes_t snd_pcm_mmap_offset(snd_pcm_t *pcm)
321 {
322 assert(pcm);
323 return *pcm->appl.ptr % pcm->buffer_size;
324 }
325
snd_pcm_mmap_hw_offset(snd_pcm_t * pcm)326 static inline snd_pcm_uframes_t snd_pcm_mmap_hw_offset(snd_pcm_t *pcm)
327 {
328 assert(pcm);
329 return *pcm->hw.ptr % pcm->buffer_size;
330 }
331
snd_pcm_channel_area_addr(const snd_pcm_channel_area_t * area,snd_pcm_uframes_t offset)332 static inline void *snd_pcm_channel_area_addr(const snd_pcm_channel_area_t *area, snd_pcm_uframes_t offset)
333 {
334 unsigned int bitofs = area->first + area->step * offset;
335 assert(bitofs % 8 == 0);
336 return (char *) area->addr + bitofs / 8;
337 }
338
snd_pcm_channel_area_step(const snd_pcm_channel_area_t * area)339 static inline unsigned int snd_pcm_channel_area_step(const snd_pcm_channel_area_t *area)
340 {
341 assert(area->step % 8 == 0);
342 return area->step / 8;
343 }
344
_snd_pcm_writei(snd_pcm_t * pcm,const void * buffer,snd_pcm_uframes_t size)345 static inline snd_pcm_sframes_t _snd_pcm_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size)
346 {
347 /* lock handled in the callback */
348 return pcm->fast_ops->writei(pcm->fast_op_arg, buffer, size);
349 }
350
_snd_pcm_readi(snd_pcm_t * pcm,void * buffer,snd_pcm_uframes_t size)351 static inline snd_pcm_sframes_t _snd_pcm_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size)
352 {
353 /* lock handled in the callback */
354 return pcm->fast_ops->readi(pcm->fast_op_arg, buffer, size);
355 }
356
357
358
muldiv(int a,int b,int c,int * r)359 static inline int muldiv(int a, int b, int c, int *r)
360 {
361 int64_t n = (int64_t)a * b;
362 int64_t v = n / c;
363 if (v > INT_MAX) {
364 *r = 0;
365 return INT_MAX;
366 }
367 if (v < INT_MIN) {
368 *r = 0;
369 return INT_MIN;
370 }
371 *r = n % c;
372 return v;
373 }
374
muldiv_down(int a,int b,int c)375 static inline int muldiv_down(int a, int b, int c)
376 {
377 int64_t v = (int64_t)a * b / c;
378 if (v > INT_MAX) {
379 return INT_MAX;
380 }
381 if (v < INT_MIN) {
382 return INT_MIN;
383 }
384 return v;
385 }
386
muldiv_near(int a,int b,int c)387 static inline int muldiv_near(int a, int b, int c)
388 {
389 int r;
390 int n = muldiv(a, b, c, &r);
391 if (r >= (c + 1) / 2)
392 n++;
393 return n;
394 }
395
396 #define SND_PCM_HW_PARBIT_ACCESS (1U << SND_PCM_HW_PARAM_ACCESS)
397 #define SND_PCM_HW_PARBIT_FORMAT (1U << SND_PCM_HW_PARAM_FORMAT)
398 #define SND_PCM_HW_PARBIT_CHANNELS (1U << SND_PCM_HW_PARAM_CHANNELS)
399 #define SND_PCM_HW_PARBIT_RATE (1U << SND_PCM_HW_PARAM_RATE)
400 #define SND_PCM_HW_PARBIT_PERIOD_TIME (1U << SND_PCM_HW_PARAM_PERIOD_TIME)
401 #define SND_PCM_HW_PARBIT_PERIOD_SIZE (1U << SND_PCM_HW_PARAM_PERIOD_SIZE)
402 #define SND_PCM_HW_PARBIT_PERIODS (1U << SND_PCM_HW_PARAM_PERIODS)
403 #define SND_PCM_HW_PARBIT_BUFFER_TIME (1U << SND_PCM_HW_PARAM_BUFFER_TIME)
404 #define SND_PCM_HW_PARBIT_BUFFER_SIZE (1U << SND_PCM_HW_PARAM_BUFFER_SIZE)
405 #define SND_PCM_HW_PARBIT_SAMPLE_BITS (1U << SND_PCM_HW_PARAM_SAMPLE_BITS)
406 #define SND_PCM_HW_PARBIT_FRAME_BITS (1U << SND_PCM_HW_PARAM_FRAME_BITS)
407 #define SND_PCM_HW_PARBIT_PERIOD_BYTES (1U << SND_PCM_HW_PARAM_PERIOD_BYTES)
408 #define SND_PCM_HW_PARBIT_BUFFER_BYTES (1U << SND_PCM_HW_PARAM_BUFFER_BYTES)
409
410 #define SND_PCM_ACCBIT_MMAP ((1U << SND_PCM_ACCESS_MMAP_INTERLEAVED) | \
411 (1U << SND_PCM_ACCESS_MMAP_NONINTERLEAVED) | \
412 (1U << SND_PCM_ACCESS_MMAP_COMPLEX))
413 #define SND_PCM_ACCBIT_MMAPI (1U << SND_PCM_ACCESS_MMAP_INTERLEAVED)
414 #define SND_PCM_ACCBIT_MMAPN (1U << SND_PCM_ACCESS_MMAP_NONINTERLEAVED)
415 #define SND_PCM_ACCBIT_MMAPC (1U << SND_PCM_ACCESS_MMAP_COMPLEX)
416
417 #define SND_PCM_ACCBIT_SHM ((1U << SND_PCM_ACCESS_MMAP_INTERLEAVED) | \
418 (1U << SND_PCM_ACCESS_RW_INTERLEAVED) | \
419 (1U << SND_PCM_ACCESS_MMAP_NONINTERLEAVED) | \
420 (1U << SND_PCM_ACCESS_RW_NONINTERLEAVED))
421 #define SND_PCM_ACCBIT_SHMI ((1U << SND_PCM_ACCESS_MMAP_INTERLEAVED) | \
422 (1U << SND_PCM_ACCESS_RW_INTERLEAVED))
423 #define SND_PCM_ACCBIT_SHMN ((1U << SND_PCM_ACCESS_MMAP_NONINTERLEAVED) | \
424 (1U << SND_PCM_ACCESS_RW_NONINTERLEAVED))
425
426 #define SND_PCM_FMTBIT_LINEAR \
427 ((1U << SND_PCM_FORMAT_S8) | \
428 (1U << SND_PCM_FORMAT_U8) | \
429 (1U << SND_PCM_FORMAT_S16_LE) | \
430 (1U << SND_PCM_FORMAT_S16_BE) | \
431 (1U << SND_PCM_FORMAT_U16_LE) | \
432 (1U << SND_PCM_FORMAT_U16_BE) | \
433 (1U << SND_PCM_FORMAT_S24_LE) | \
434 (1U << SND_PCM_FORMAT_S24_BE) | \
435 (1U << SND_PCM_FORMAT_U24_LE) | \
436 (1U << SND_PCM_FORMAT_U24_BE) | \
437 (1U << SND_PCM_FORMAT_S32_LE) | \
438 (1U << SND_PCM_FORMAT_S32_BE) | \
439 (1U << SND_PCM_FORMAT_U32_LE) | \
440 (1U << SND_PCM_FORMAT_U32_BE))
441
442 void snd_pcm_hw_param_dump(const snd_pcm_hw_params_t *params, snd_pcm_hw_param_t var);
443
444 int snd_pcm_hw_param_empty(const snd_pcm_hw_params_t *params,
445 snd_pcm_hw_param_t var);
446 int snd_pcm_hw_param_always_eq(const snd_pcm_hw_params_t *params,
447 snd_pcm_hw_param_t var,
448 const snd_pcm_hw_params_t *params1);
449 int snd_pcm_hw_param_never_eq(const snd_pcm_hw_params_t *params,
450 snd_pcm_hw_param_t var,
451 const snd_pcm_hw_params_t *params1);
452 int snd_pcm_hw_param_get(const snd_pcm_hw_params_t *params, snd_pcm_hw_param_t var,
453 unsigned int *val, int *dir);
454 int snd_pcm_hw_param_get_min(const snd_pcm_hw_params_t *params,
455 snd_pcm_hw_param_t var,
456 unsigned int *val, int *dir);
457 int snd_pcm_hw_param_get_max(const snd_pcm_hw_params_t *params,
458 snd_pcm_hw_param_t var,
459 unsigned int *val, int *dir);
460
461 void _snd_pcm_hw_param_any(snd_pcm_hw_params_t *params, snd_pcm_hw_param_t var);
462 void _snd_pcm_hw_params_any(snd_pcm_hw_params_t *params);
463
464 int _snd_pcm_hw_param_set_mask(snd_pcm_hw_params_t *params,
465 snd_pcm_hw_param_t var, const snd_interval_t *mask);
466 int _snd_pcm_hw_param_set_range(snd_pcm_hw_params_t *params,
467 snd_pcm_hw_param_t var, const snd_interval_t *val);
468
469 int _snd_pcm_hw_param_set(snd_pcm_hw_params_t *param,
470 snd_pcm_hw_param_t var, unsigned int val, int dir);
471
472 int _snd_pcm_hw_param_set_min(snd_pcm_hw_params_t *params,
473 snd_pcm_hw_param_t var, unsigned int val, int dir);
474 int _snd_pcm_hw_param_set_max(snd_pcm_hw_params_t *params,
475 snd_pcm_hw_param_t var, unsigned int val, int dir);
476 int _snd_pcm_hw_param_set_minmax(snd_pcm_hw_params_t *params,
477 snd_pcm_hw_param_t var,
478 unsigned int min, int mindir,
479 unsigned int max, int maxdir);
480 int _snd_pcm_hw_param_refine(snd_pcm_hw_params_t *params,
481 snd_pcm_hw_param_t var,
482 const snd_pcm_hw_params_t *src);
483 int _snd_pcm_hw_params_refine(snd_pcm_hw_params_t *params,
484 unsigned int vars,
485 const snd_pcm_hw_params_t *src);
486
487 int snd_pcm_hw_param_refine_near(snd_pcm_t *pcm,
488 snd_pcm_hw_params_t *params,
489 snd_pcm_hw_param_t var,
490 const snd_pcm_hw_params_t *src);
491 int snd_pcm_hw_param_refine_multiple(snd_pcm_t *pcm,
492 snd_pcm_hw_params_t *params,
493 snd_pcm_hw_param_t var,
494 const snd_pcm_hw_params_t *src);
495
496 int snd_pcm_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
497 int snd_pcm_hw_refine_soft(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
498 int snd_pcm_hw_refine_slave(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
499 int (*cprepare)(snd_pcm_t *pcm,
500 snd_pcm_hw_params_t *params),
501 int (*cchange)(snd_pcm_t *pcm,
502 snd_pcm_hw_params_t *params,
503 snd_pcm_hw_params_t *sparams),
504 int (*sprepare)(snd_pcm_t *pcm,
505 snd_pcm_hw_params_t *params),
506 int (*schange)(snd_pcm_t *pcm,
507 snd_pcm_hw_params_t *params,
508 snd_pcm_hw_params_t *sparams),
509 int (*srefine)(snd_pcm_t *pcm,
510 snd_pcm_hw_params_t *sparams));
511 int snd_pcm_hw_params_slave(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
512 int (*cchange)(snd_pcm_t *pcm,
513 snd_pcm_hw_params_t *params,
514 snd_pcm_hw_params_t *sparams),
515 int (*sprepare)(snd_pcm_t *pcm,
516 snd_pcm_hw_params_t *params),
517 int (*schange)(snd_pcm_t *pcm,
518 snd_pcm_hw_params_t *params,
519 snd_pcm_hw_params_t *sparams),
520 int (*sparams)(snd_pcm_t *pcm,
521 snd_pcm_hw_params_t *sparams));
522
523 int snd_pcm_hw_param_set(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
524 snd_set_mode_t mode,
525 snd_pcm_hw_param_t var, unsigned int val, int dir);
526 int snd_pcm_hw_param_set_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
527 snd_pcm_hw_param_t var, unsigned int *rval, int *dir);
528 int snd_pcm_hw_param_set_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
529 snd_pcm_hw_param_t var, unsigned int *rval, int *dir);
530 int snd_pcm_hw_param_set_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
531 snd_set_mode_t mode,
532 snd_pcm_hw_param_t var, unsigned int *val, int *dir);
533 int snd_pcm_hw_param_set_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
534 snd_set_mode_t mode,
535 snd_pcm_hw_param_t var, unsigned int *val, int *dir);
536 int snd_pcm_hw_param_set_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
537 snd_set_mode_t mode,
538 snd_pcm_hw_param_t var,
539 unsigned int *min, int *mindir,
540 unsigned int *max, int *maxdir);
541 int snd_pcm_hw_param_set_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
542 snd_pcm_hw_param_t var,
543 unsigned int *val, int *dir);
544 int snd_pcm_hw_param_set_mask(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
545 snd_set_mode_t mode,
546 snd_pcm_hw_param_t var, const snd_interval_t *val);
547
548 int _snd_pcm_hw_params_internal(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
549
snd_pcm_hw_param_can_changed(snd_pcm_hw_params_t * params,snd_pcm_hw_param_t var)550 static inline int snd_pcm_hw_param_can_changed(
551 snd_pcm_hw_params_t *params, snd_pcm_hw_param_t var)
552 {
553 #if 0
554 return params->cmask & (1 << var);
555 #endif
556 return 1;
557 }
558
snd_pcm_hw_param_change(snd_pcm_hw_params_t * params,snd_pcm_hw_param_t var)559 static inline int snd_pcm_hw_param_change(
560 snd_pcm_hw_params_t *params, snd_pcm_hw_param_t var)
561 {
562 #if 0
563 params->cmask |= (1 << var);
564 #endif
565 return 0;
566 }
567
568
569 #define SND_PCM_APPEND (1<<8)
570
571 int snd_pcm_open_config(snd_pcm_t **pcmp, const snd_pcm_config_t *pcm_config,
572 snd_pcm_stream_t stream, int mode);
573
574
575 /* PCM Helper Functions */
576 int snd_pcm_format_signed(snd_pcm_format_t format);
577 int snd_pcm_format_unsigned(snd_pcm_format_t format);
578 int snd_pcm_format_linear(snd_pcm_format_t format);
579 int snd_pcm_format_little_endian(snd_pcm_format_t format);
580 int snd_pcm_format_big_endian(snd_pcm_format_t format);
581 int snd_pcm_format_width(snd_pcm_format_t format);
582 snd_pcm_format_t snd_pcm_build_linear_format(int width, int pwidth, int unsignd, int big_endian);
583
584 #if 0
585 static inline snd_interval_t *hw_param_interval(snd_pcm_hw_params_t *params,
586 snd_pcm_hw_param_t var)
587 {
588 return ¶ms->intervals[var];
589 }
590
591 int snd_interval_refine(snd_interval_t *i, const snd_interval_t *v);
592 #endif
593 snd_pcm_chmap_query_t **_snd_pcm_make_single_query_chmaps(const snd_pcm_chmap_t *src);
594
595
596 #ifdef __cplusplus
597 }
598 #endif
599 #endif /* __AW_ALSA_PCM_LOCAL_H */
600