1 /**
2  * \file pcm/pcm.c
3  * \ingroup PCM
4  * \brief PCM Interface
5  * \author Jaroslav Kysela <perex@perex.cz>
6  * \author Abramo Bagnara <abramo@alsa-project.org>
7  * \date 2000-2001
8  *
9  * PCM Interface is designed to write or read digital audio frames. A
10  * frame is the data unit converted into/from sound in one time unit
11  * (1/rate seconds), by example if you set your playback PCM rate to
12  * 44100 you'll hear 44100 frames per second. The size in bytes of a
13  * frame may be obtained from bits needed to store a sample and
14  * channels count.
15  *
16  * See the \ref pcm page for more details.
17  */
18 /*
19  *  PCM Interface - main file
20  *  Copyright (c) 1998 by Jaroslav Kysela <perex@perex.cz>
21  *  Copyright (c) 2000 by Abramo Bagnara <abramo@alsa-project.org>
22  *
23  *   This library is free software; you can redistribute it and/or modify
24  *   it under the terms of the GNU Lesser General Public License as
25  *   published by the Free Software Foundation; either version 2.1 of
26  *   the License, or (at your option) any later version.
27  *
28  *   This program is distributed in the hope that it will be useful,
29  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
30  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
31  *   GNU Lesser General Public License for more details.
32  *
33  *   You should have received a copy of the GNU Lesser General Public
34  *   License along with this library; if not, write to the Free Software
35  *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
36  *
37  */
38 
39 /*! \page pcm PCM (digital audio) interface
40 
41 <P>Although abbreviation PCM stands for Pulse Code Modulation, we are
42 understanding it as general digital audio processing with volume samples
43 generated in continuous time periods.</P>
44 
45 <P>The analog signal is recorded via analog to digital converters (ADC).
46 The digital value (de-facto a volume at a specific time) obtained
47 from ADC can be further processed. The following picture shows a perfect
48 sinus waveform:</P>
49 
50 <BR>
51 \image html wave1.gif
52 
53 <P>Next image shows digitized representation:</P>
54 
55 <BR>
56 \image html wave2.gif
57 
58 <P>As you may see, the quality of digital audio signal depends on the time
59 (recording rate) and voltage resolution (usually in an linear integer
60 representation with basic unit one bit).</P>
61 
62 <P>The stored digital signal can be converted back to voltage (analog)
63 representation via digital to analog converters (DAC).</P>
64 
65 <P>One digital value is called sample. More samples are collected to frames
66 (frame is terminology for ALSA) depending on count of converters used at one
67 specific time. One frame might contain one sample (when only one converter is
68 used - mono) or more samples (for example: stereo has signals from two converters
69 recorded at same time). Digital audio stream contains collection of frames
70 recorded at boundaries of continuous time periods.</P>
71 
72 \section pcm_general_overview General overview
73 
74 ALSA uses the ring buffer to store outgoing (playback) and incoming (capture,
75 record) samples. There are two pointers being maintained to allow
76 a precise communication between application and device pointing to current
77 processed sample by hardware and last processed sample by application.
78 The modern audio chips allow to program the transfer time periods.
79 It means that the stream of samples is divided to small chunks. Device
80 acknowledges to application when the transfer of a chunk is complete.
81 
82 \section pcm_transfer Transfer methods in UNIX environments
83 
84 In the UNIX environment, data chunk acknowledges are received via standard I/O
85 calls or event waiting routines (poll or select function). To accomplish
86 this list, the asynchronous notification of acknowledges should be listed
87 here. The ALSA implementation for these methods is described in
88 the \ref alsa_transfers section.
89 
90 \subsection pcm_transfer_io Standard I/O transfers
91 
92 The standard I/O transfers are using the read (see 'man 2 read') and write
93 (see 'man 2 write') C functions. There are two basic behaviours of these
94 functions - blocked and non-blocked (see the O_NONBLOCK flag for the
95 standard C open function - see 'man 2 open'). In non-blocked behaviour,
96 these I/O functions never stops, they return -EAGAIN error code, when no
97 data can be transferred (the ring buffer is full in our case). In blocked
98 behaviour, these I/O functions stop and wait until there is a room in the
99 ring buffer (playback) or until there are new samples (capture). The ALSA
100 implementation can be found in the \ref alsa_pcm_rw section.
101 
102 \subsection pcm_transfer_event Event waiting routines
103 
104 The poll or select functions (see 'man 2 poll' or 'man 2 select' for further
105 details) allows to receive requests/events from the device while
106 an application is waiting on events from other sources (like keyboard, screen,
107 network etc.), too. \ref snd_pcm_poll_descriptors can be used to get file
108 descriptors to poll or select on (note that wait direction might be different
109 than expected - do not use only returned file descriptors, but handle
110 events member as well - see \ref snd_pcm_poll_descriptors function
111 description for more details and \ref snd_pcm_poll_descriptors_revents for
112 events demangling). The implemented transfer routines can be found in
113 the \ref alsa_transfers section.
114 
115 \subsection pcm_transfer_async Asynchronous notification
116 
117 ALSA driver and library knows to handle the asynchronous notifications over
118 the SIGIO signal. This signal allows to interrupt application and transfer
119 data in the signal handler. For further details see the sigaction function
120 ('man 2 sigaction'). The section \ref pcm_async describes the ALSA API for
121 this extension. The implemented transfer routines can be found in the
122 \ref alsa_transfers section.
123 
124 \section pcm_open_behaviour Blocked and non-blocked open
125 
126 The ALSA PCM API uses a different behaviour when the device is opened
127 with blocked or non-blocked mode. The mode can be specified with
128 \a mode argument in #snd_pcm_open() function.
129 The blocked mode is the default (without #SND_PCM_NONBLOCK mode).
130 In this mode, the behaviour is that if the resources have already used
131 with another application, then it blocks the caller, until resources are
132 free. The non-blocked behaviour (with #SND_PCM_NONBLOCK)
133 doesn't block the caller in any way and returns -EBUSY error when the
134 resources are not available. Note that the mode also determines the
135 behaviour of standard I/O calls, returning -EAGAIN when non-blocked mode is
136 used and the ring buffer is full (playback) or empty (capture).
137 The operation mode for I/O calls can be changed later with
138 the #snd_pcm_nonblock() function.
139 
140 \section pcm_async Asynchronous mode
141 
142 There is also possibility to receive asynchronous notification after
143 specified time periods. You may see the #SND_PCM_ASYNC
144 mode for #snd_pcm_open() function and
145 #snd_async_add_pcm_handler() function for further details.
146 
147 \section pcm_handshake Handshake between application and library
148 
149 The ALSA PCM API design uses the states to determine the communication
150 phase between application and library. The actual state can be determined
151 using #snd_pcm_state() call. There are these states:
152 
153 \par SND_PCM_STATE_OPEN
154 The PCM device is in the open state. After the #snd_pcm_open() open call,
155 the device is in this state. Also, when #snd_pcm_hw_params() call fails,
156 then this state is entered to force application calling
157 #snd_pcm_hw_params() function to set right communication
158 parameters.
159 
160 \par SND_PCM_STATE_SETUP
161 The PCM device has accepted communication parameters and it is waiting
162 for #snd_pcm_prepare() call to prepare the hardware for
163 selected operation (playback or capture).
164 
165 \par SND_PCM_STATE_PREPARED
166 The PCM device is prepared for operation. Application can use
167 #snd_pcm_start() call, write or read data to start
168 the operation.
169 
170 \par SND_PCM_STATE_RUNNING
171 The PCM device has been started and is running. It processes the samples. The stream can
172 be stopped using the #snd_pcm_drop() or
173 #snd_pcm_drain() calls.
174 
175 \par SND_PCM_STATE_XRUN
176 The PCM device reached overrun (capture) or underrun (playback).
177 You can use the -EPIPE return code from I/O functions
178 (#snd_pcm_writei(), #snd_pcm_writen(), #snd_pcm_readi(), #snd_pcm_readn())
179 to determine this state without checking
180 the actual state via #snd_pcm_state() call. It is recommended to use
181 the helper function #snd_pcm_recover() to recover from this state, but you can also use #snd_pcm_prepare(),
182 #snd_pcm_drop() or #snd_pcm_drain() calls.
183 
184 \par SND_PCM_STATE_DRAINING
185 The device is in this state when application using the capture mode
186 called #snd_pcm_drain() function. Until all data are
187 read from the internal ring buffer using I/O routines
188 (#snd_pcm_readi(), #snd_pcm_readn()),
189 then the device stays in this state.
190 
191 \par SND_PCM_STATE_PAUSED
192 The device is in this state when application called
193 the #snd_pcm_pause() function until the pause is released.
194 Not all hardware supports this feature. Application should check the
195 capability with the #snd_pcm_hw_params_can_pause().
196 
197 \par SND_PCM_STATE_SUSPENDED
198 The device is in the suspend state provoked with the power management
199 system. The stream can be resumed using #snd_pcm_resume()
200 call, but not all hardware supports this feature. Application should check
201 the capability with the #snd_pcm_hw_params_can_resume().
202 In other case, the calls #snd_pcm_prepare(),
203 #snd_pcm_drop(), #snd_pcm_drain() can be used
204 to leave this state.
205 
206 \par SND_PCM_STATE_DISCONNECTED
207 The device is physicaly disconnected. It does not accept any I/O calls in this state.
208 
209 \section pcm_formats PCM formats
210 
211 The full list of formats present the #snd_pcm_format_t type.
212 The 24-bit linear samples use 32-bit physical space, but the sample is
213 stored in the lower three bytes. Some hardware does not support processing of full
214 range, thus you may get the significant bits for linear samples via
215 #snd_pcm_hw_params_get_sbits() function. The example: ICE1712
216 chips support 32-bit sample processing, but low byte is ignored (playback)
217 or zero (capture). The function snd_pcm_hw_params_get_sbits()
218 returns 24 in this case. The significant bits are related to the usable
219 sample bits (width) not the physical sample space.
220 
221 \section alsa_transfers ALSA transfers
222 
223 There are two methods to transfer samples in application. The first method
224 is the standard read / write one. The second method, uses the direct audio
225 buffer to communicate with the device while ALSA library manages this space
226 itself. You can find examples of all communication schemes for playback
227 in \link example_test_pcm Sine-wave generator example \endlink. To complete the
228 list, we should note that #snd_pcm_wait() function contains
229 embedded poll waiting implementation.
230 
231 \subsection alsa_pcm_rw Read / Write transfer
232 
233 There are two versions of read / write routines. The first expects the
234 interleaved samples at input (#SND_PCM_ACCESS_RW_INTERLEAVED access method),
235 and the second one expects non-interleaved (samples in separated buffers -
236 #SND_PCM_ACCESS_RW_NONINTERLEAVED access method) at input. There are these
237 functions for interleaved transfers: #snd_pcm_writei()
238 #snd_pcm_readi(). For non-interleaved transfers, there are
239 these functions: #snd_pcm_writen() and #snd_pcm_readn().
240 
241 \subsection alsa_mmap_rw Direct Read / Write transfer (via mmap'ed areas)
242 
243 Three kinds of organization of ring buffer memory areas exist in ALSA API.
244 Access #SND_PCM_ACCESS_MMAP_INTERLEAVED has interleaved samples. Access
245 #SND_PCM_ACCESS_MMAP_NONINTERLEAVED expects continous sample areas for
246 one channel. Access #SND_PCM_ACCESS_MMAP_COMPLEX does not fit to interleaved
247 and non-interleaved ring buffer organization.
248 
249 There are two functions for this kind of transfer. Application can get an
250 access to memory areas via #snd_pcm_mmap_begin() function.
251 This function returns the areas (single area is equal to a channel)
252 containing the direct pointers to memory and sample position description
253 in #snd_pcm_channel_area_t structure. After application
254 transfers the data in the memory areas, then it must be acknowledged
255 the end of transfer via #snd_pcm_mmap_commit() function
256 to allow the ALSA library update the pointers to ring buffer. This kind of
257 communication is also called "zero-copy", because the device does not require
258 to copy the samples from application to another place in system memory.
259 
260 If you like to use the compatibility functions in mmap mode, there are
261 read / write routines equaling to standard read / write transfers. Using
262 these functions discards the benefits of direct access to memory region.
263 See the #snd_pcm_mmap_readi(),
264 #snd_pcm_mmap_writei(), #snd_pcm_mmap_readn()
265 and #snd_pcm_mmap_writen() functions. These functions use
266 #snd_pcm_areas_copy() internally.
267 
268 \section pcm_errors Error codes
269 
270 \par -EPIPE
271 
272 This error means xrun (underrun for playback or overrun for capture).
273 The underrun can happen when an application does not feed new samples
274 in time to alsa-lib (due CPU usage). The overrun can happen when
275 an application does not take new captured samples in time from alsa-lib.
276 
277 \par -ESTRPIPE
278 
279 This error means that system has suspended drivers. The application
280 should wait in loop when snd_pcm_resume() != -EAGAIN and then
281 call snd_pcm_prepare() when snd_pcm_resume() return an error code.
282 If snd_pcm_resume() does not fail (a zero value is returned), driver
283 supports resume and the snd_pcm_prepare() call can be ommited.
284 
285 \par -EBADFD
286 
287 This error means that the device is in a bad state. It means that
288 the handshake between application and alsa-lib is corrupted.
289 
290 \par -ENOTTY, -ENODEV
291 
292 This error can happen when device is physically removed (for example
293 some hotplug devices like USB or PCMCIA, CardBus or ExpressCard
294 can be removed on the fly).
295 
296 \par -ENODATA
297 
298 This error can happen if the device data transfer is dependent on
299 an external condition and that condition is not met. For example,
300 PCM device for echo reference as described by SND_USE_CASE_MOD_ECHO_REF
301 UCM token, may return -ENODATA if the linked playback stream has not been
302 started.
303 
304 There is no defined recovery or event mechanism to signal the data / link
305 availability at the moment. The PCM must be completely restarted until
306 the mechanism is designed. The #snd_pcm_recover() function cannot be
307 used for this.
308 
309 \section pcm_params Managing parameters
310 
311 The ALSA PCM device uses two groups of PCM related parameters. The hardware
312 parameters contains the stream description like format, rate, count of
313 channels, ring buffer size etc. The software parameters contains the
314 software (driver) related parameters. The communication behaviour can be
315 controlled via these parameters, like automatic start, automatic stop,
316 interrupting (chunk acknowledge) etc. The software parameters can be
317 modified at any time (when valid hardware parameters are set). It includes
318 the running state as well.
319 
320 \subsection pcm_hw_params Hardware related parameters
321 
322 The ALSA PCM devices use the parameter refining system for hardware
323 parameters - #snd_pcm_hw_params_t. It means, that
324 application choose the full-range of configurations at first and then
325 application sets single parameters until all parameters are elementary
326 (definite).
327 
328 \par Access modes
329 
330 ALSA knows about five access modes. The first three can be used for direct
331 communication. The access mode #SND_PCM_ACCESS_MMAP_INTERLEAVED
332 determines the direct memory area and interleaved sample organization.
333 Interleaved organization means, that samples from channels are mixed together.
334 The access mode #SND_PCM_ACCESS_MMAP_NONINTERLEAVED
335 determines the direct memory area and non-interleaved sample organization.
336 Each channel has a separate buffer in the case. The complex direct memory
337 organization represents the #SND_PCM_ACCESS_MMAP_COMPLEX
338 access mode. The sample organization does not fit the interleaved or
339 non-interleaved access modes in the case. The last two access modes
340 describes the read / write access methods.
341 The #SND_PCM_ACCESS_RW_INTERLEAVED access represents the read /
342 write interleaved access and the #SND_PCM_ACCESS_RW_NONINTERLEAVED
343 represents the non-interleaved access.
344 
345 \par Formats
346 
347 The full list of formats is available in #snd_pcm_format_t
348 enumeration.
349 
350 \subsection pcm_sw_params Software related parameters
351 
352 These parameters - #snd_pcm_sw_params_t can be modified at
353 any time including the running state.
354 
355 \par Minimum available count of frames
356 
357 This parameter controls the wakeup point. If the count of available frames
358 is equal or greater than this value, then application will be activated.
359 
360 \par Timestamp mode
361 
362 The timestamp mode specifies, if timestamps are activated. Currently, only
363 #SND_PCM_TSTAMP_NONE and #SND_PCM_TSTAMP_MMAP
364 modes are known. The mmap mode means that timestamp is taken
365 on every period time boundary. Corresponding position in the ring buffer
366 assigned to timestamp can be obtained using #snd_pcm_htimestamp() function.
367 
368 \par Transfer align
369 
370 The read / write transfers can be aligned to this sample count. The modulo
371 is ignored by device. Usually, this value is set to one (no align).
372 
373 \par Start threshold
374 
375 The start threshold parameter is used to determine the start point in
376 stream. For playback, if the frame count in the ring buffer is equal or greater
377 than the start threshold parameter and the stream is not running, the stream
378 will be started automatically from the device. For capture, if the application
379 wants to read count of frames equal or greater then the stream will be started.
380 If you want to use explicit start (#snd_pcm_start), you can set this value
381 greater than the ring buffer size (in frames). For that simply using a large
382 constant such as LONG_MAX or the boundary value is not a bad idea.
383 
384 \par Stop threshold
385 
386 Similarly, the stop threshold parameter is used to automatically stop
387 the running stream, when the available frames crosses this boundary.
388 It means, for playback, the empty samples in ring buffer and for capture,
389 the filled (used) samples in ring buffer.
390 
391 \par Silence threshold
392 
393 The silence threshold specifies the count of frames before an underrun when the
394 buffer gets filled with frames of silence according to the silence size parameter
395 ahead of the current application pointer for playback. It is usable for applications
396 when an underrun is possible (like tasks depending on network I/O etc.). If
397 application wants to manage the ahead samples itself, the #snd_pcm_rewind() function
398 allows to forget the last samples in the stream.
399 
400 \section pcm_status Obtaining stream status
401 
402 The stream status is stored in #snd_pcm_status_t structure.
403 These parameters can be obtained: the current stream state -
404 #snd_pcm_status_get_state(), timestamp of trigger -
405 #snd_pcm_status_get_trigger_tstamp(), timestamp of last
406 pointer update #snd_pcm_status_get_tstamp(), delay in frames -
407 #snd_pcm_status_get_delay(), available count in frames -
408 #snd_pcm_status_get_avail(), maximum available frames -
409 #snd_pcm_status_get_avail_max(), ADC over-range count in
410 frames - #snd_pcm_status_get_overrange(). The last two
411 parameters - avail_max and overrange are reset to zero after the status
412 call.
413 
414 \subsection pcm_status_fast Obtaining stream state fast and update r/w pointer
415 
416 <p>
417 The function #snd_pcm_avail_update() updates the current
418 available count of frames for writing (playback) or filled frames for
419 reading (capture). This call is mandatory for updating actual r/w pointer.
420 Using standalone, it is a light method to obtain current stream position,
421 because it does not require the user <-> kernel context switch, but the value
422 is less accurate, because ring buffer pointers are updated in kernel drivers
423 only when an interrupt occurs. If you want to get accurate stream state,
424 use functions #snd_pcm_avail(), #snd_pcm_delay() or #snd_pcm_avail_delay().
425 </p>
426 <p>
427 The function #snd_pcm_avail() reads the current hardware pointer
428 in the ring buffer from hardware and calls #snd_pcm_avail_update() then.
429 </p>
430 <p>
431 The function #snd_pcm_delay() returns the delay in frames.
432 For playback, it means count of frames in the ring buffer before
433 the next frames will be sent to DAC. For capture, it means count of frames
434 in the ring buffer before the next frames will be captured from ADC. It works
435 only when the stream is in the running or draining (playback only) state.
436 Note that this function does not update the current r/w pointer for applications,
437 so the function #snd_pcm_avail_update() must be called afterwards
438 before any read/write begin+commit operations.
439 </p>
440 <p>
441 The function #snd_pcm_avail_delay() combines #snd_pcm_avail() and
442 #snd_pcm_delay() and returns both values in sync.
443 </p>
444 
445 \section pcm_action Managing the stream state
446 
447 The following functions directly and indirectly affect the stream state:
448 
449 \par snd_pcm_hw_params
450 The #snd_pcm_hw_params() function brings the stream state
451 to #SND_PCM_STATE_SETUP
452 if successfully finishes, otherwise the state #SND_PCM_STATE_OPEN
453 is entered.
454 When it is brought to SETUP state, this function automatically
455 calls #snd_pcm_prepare() function to bring to the PREPARED state
456 as below.
457 
458 \par snd_pcm_prepare
459 The #snd_pcm_prepare() function enters from #SND_PCM_STATE_SETUP
460 to the #SND_PCM_STATE_PREPARED after a successful finish.
461 
462 \par snd_pcm_start
463 The #snd_pcm_start() function enters
464 the #SND_PCM_STATE_RUNNING after a successful finish.
465 
466 \par snd_pcm_drop
467 The #snd_pcm_drop() function enters the
468 #SND_PCM_STATE_SETUP state.
469 
470 \par snd_pcm_drain
471 The #snd_pcm_drain() function enters the
472 #SND_PCM_STATE_DRAINING, if
473 the capture device has some samples in the ring buffer otherwise
474 #SND_PCM_STATE_SETUP state is entered.
475 
476 \par snd_pcm_pause
477 The #snd_pcm_pause() function enters the
478 #SND_PCM_STATE_PAUSED or #SND_PCM_STATE_RUNNING.
479 
480 \par snd_pcm_writei, snd_pcm_writen
481 The #snd_pcm_writei() and #snd_pcm_writen()
482 functions can conditionally start the stream -
483 #SND_PCM_STATE_RUNNING. They depend on the start threshold
484 software parameter.
485 
486 \par snd_pcm_readi, snd_pcm_readn
487 The #snd_pcm_readi() and #snd_pcm_readn()
488 functions can conditionally start the stream -
489 #SND_PCM_STATE_RUNNING. They depend on the start threshold
490 software parameter.
491 
492 \section pcm_sync Streams synchronization
493 
494 There are two functions allowing link multiple streams together. In the
495 case, the linking means that all operations are synchronized. Because the
496 drivers cannot guarantee the synchronization (sample resolution) on hardware
497 lacking this feature, the #snd_pcm_info_get_sync() function
498 returns synchronization ID - #snd_pcm_sync_id_t, which is equal
499 for hardware synchronized streams. When the #snd_pcm_link()
500 function is called, all operations managing the stream state for these two
501 streams are joined. The opposite function is #snd_pcm_unlink().
502 
503 \section pcm_thread_safety Thread-safety
504 
505 When the library is configured with the proper option, some PCM functions
506 (e.g. #snd_pcm_avail_update()) are thread-safe and can be called concurrently
507 from multiple threads.  Meanwhile, some functions (e.g. #snd_pcm_hw_params())
508 aren't thread-safe, and application needs to call them carefully when they
509 are called from multiple threads.  In general, all the functions that are
510 often called during streaming are covered as thread-safe.
511 
512 This thread-safe behavior can be disabled also by passing 0 to the environment
513 variable LIBASOUND_THREAD_SAFE, e.g.
514 \code
515 LIBASOUND_THREAD_SAFE=0 aplay foo.wav
516 \endcode
517 for making the debugging easier.
518 
519 \section pcm_dev_names PCM naming conventions
520 
521 The ALSA library uses a generic string representation for names of devices.
522 The devices might be virtual, physical or a mix of both. The generic string
523 is passed to #snd_pcm_open() or #snd_pcm_open_lconf().
524 It contains two parts: device name and arguments. Devices and arguments are described
525 in configuration files. The usual place for default definitions is at /usr/share/alsa/alsa.conf.
526 For detailed descriptions about integrated PCM plugins look to \ref pcm_plugins.
527 
528 \subsection pcm_dev_names_default Default device
529 
530 The default device is equal to plug plugin with hw plugin as slave. The defaults are
531 used:
532 
533 \code
534 defaults.pcm.card 0
535 defaults.pcm.device 0
536 defaults.pcm.subdevice -1
537 \endcode
538 
539 These defaults can be freely overwritten in local configuration files.
540 
541 Example:
542 
543 \code
544 default
545 \endcode
546 
547 \subsection pcm_dev_names_hw HW device
548 
549 The hw device description uses the hw plugin. The three arguments (in order: CARD,DEV,SUBDEV)
550 specify card number or identifier, device number and subdevice number (-1 means any).
551 
552 Example:
553 
554 \code
555 hw
556 hw:0
557 hw:0,0
558 hw:supersonic,1
559 hw:soundwave,1,2
560 hw:DEV=1,CARD=soundwave,SUBDEV=2
561 \endcode
562 
563 \subsection pcm_dev_names_plughw Plug->HW device
564 
565 The plughw device description uses the plug plugin and hw plugin as slave. The arguments
566 are same as for hw device.
567 
568 Example:
569 
570 \code
571 plughw
572 plughw:0
573 plughw:0,0
574 plughw:supersonic,1
575 plughw:soundwave,1,2
576 plughw:DEV=1,CARD=soundwave,SUBDEV=2
577 \endcode
578 
579 \subsection pcm_dev_names_plug Plug device
580 
581 The plug device uses the plug plugin. The one SLAVE argument specifies the slave plugin.
582 
583 Example:
584 
585 \code
586 plug:mypcmdef
587 plug:hw
588 plug:'hw:0,0'
589 plug:SLAVE=hw
590 \endcode
591 
592 \subsection pcm_dev_names_shm Shared memory device
593 
594 The shm device uses the shm plugin. The two arguments (in order: SOCKET,PCM) specify
595 UNIX socket name (for example /tmp/alsa.socket) for server communication and server's PCM name.
596 
597 Example:
598 
599 \code
600 shm:'/tmp/alsa.sock',default
601 shm:SOCKET='/tmp/alsa.sock',PCM=default
602 \endcode
603 
604 \subsection pcm_dev_names_tee Tee device
605 
606 The tee device stores contents of a stream to given file plus transfers it to given slave plugin.
607 The three arguments (in order: SLAVE,FILE,FORMAT) specify slave plugin, filename and file format.
608 
609 Example:
610 
611 \code
612 tee:hw,'/tmp/out.raw',raw
613 \endcode
614 
615 \subsection pcm_dev_names_file File device
616 
617 The file device is file plugin with null plugin as slave. The arguments (in order: FILE,FORMAT)
618 specify filename and file format.
619 
620 Example:
621 
622 \code
623 file:'/tmp/out.raw',raw
624 \endcode
625 
626 \subsection pcm_dev_names_null Null device
627 
628 The null device is null plugin. This device has not any arguments.
629 
630 
631 \section pcm_examples Examples
632 
633 The full featured examples with cross-links can be found in Examples section
634 (see top of page):
635 
636 \par Sine-wave generator
637 \par
638 \link example_test_pcm alsa-lib/test/pcm.c \endlink
639 example shows various transfer methods for the playback direction.
640 
641 \par Minimalistic PCM playback code
642 \par
643 \link example_test_minimal alsa-lib/test/pcm_min.c \endlink
644 example shows the minimal code to produce a sound.
645 
646 \par Latency measuring tool
647 \par
648 \link example_test_latency alsa-lib/test/latency.c \endlink
649 example shows the measuring of minimal latency between capture and
650 playback devices.
651 
652 */
653 
654 /**
655 \example ../../test/pcm.c
656 \anchor example_test_pcm
657 Shows various transfer methods for the playback direction.
658 */
659 /**
660 \example ../../test/pcm_min.c
661 \anchor example_test_minimal
662 Shows the minimal code to produce a sound.
663 */
664 /**
665 \example ../../test/latency.c
666 \anchor example_test_latency
667 Shows the measuring of minimal latency between capture and
668 playback devices.
669 */
670 
671 #include "pcm_local.h"
672 #include <stdio.h>
673 #include <string.h>
674 #if HAVE_MALLOC_H
675 #include <malloc.h>
676 #endif
677 #include <stdarg.h>
678 #include <signal.h>
679 #include <ctype.h>
680 #include <poll.h>
681 #include <sys/mman.h>
682 #include <limits.h>
683 
684 #ifndef DOC_HIDDEN
685 /* return specific error codes for known bad PCM states */
pcm_state_to_error(snd_pcm_state_t state)686 static int pcm_state_to_error(snd_pcm_state_t state)
687 {
688 	switch (state) {
689 	case SND_PCM_STATE_XRUN:
690 		return -EPIPE;
691 	case SND_PCM_STATE_SUSPENDED:
692 		return -ESTRPIPE;
693 	case SND_PCM_STATE_DISCONNECTED:
694 		return -ENODEV;
695 	default:
696 		return 0;
697 	}
698 }
699 
700 #define P_STATE(x)	(1U << SND_PCM_STATE_ ## x)
701 #define P_STATE_RUNNABLE (P_STATE(PREPARED) | \
702 			  P_STATE(RUNNING) | \
703 			  P_STATE(XRUN) | \
704 			  P_STATE(PAUSED) | \
705 			  P_STATE(DRAINING))
706 
707 /* check whether the PCM is in the unexpected state */
bad_pcm_state(snd_pcm_t *pcm, unsigned int supported_states, unsigned int noop_states)708 static int bad_pcm_state(snd_pcm_t *pcm, unsigned int supported_states,
709 			 unsigned int noop_states)
710 {
711 	snd_pcm_state_t state;
712 	int err;
713 
714 	if (pcm->own_state_check)
715 		return 0; /* don't care, the plugin checks by itself */
716 	state = snd_pcm_state(pcm);
717 	if (noop_states & (1U << state))
718 		return 1; /* OK, return immediately */
719 	if (supported_states & (1U << state))
720 		return 0; /* OK */
721 	err = pcm_state_to_error(state);
722 	if (err < 0)
723 		return err;
724 	return -EBADFD;
725 }
726 #endif
727 
728 /**
729  * \brief get identifier of PCM handle
730  * \param pcm PCM handle
731  * \return ascii identifier of PCM handle
732  *
733  * Returns the ASCII identifier of given PCM handle. It's the same
734  * identifier specified in snd_pcm_open().
735  */
snd_pcm_name(snd_pcm_t *pcm)736 const char *snd_pcm_name(snd_pcm_t *pcm)
737 {
738 	assert(pcm);
739 	return pcm->name;
740 }
741 
742 /**
743  * \brief get type of PCM handle
744  * \param pcm PCM handle
745  * \return type of PCM handle
746  *
747  * Returns the type #snd_pcm_type_t of given PCM handle.
748  */
snd_pcm_type(snd_pcm_t *pcm)749 snd_pcm_type_t snd_pcm_type(snd_pcm_t *pcm)
750 {
751 	assert(pcm);
752 	return pcm->type;
753 }
754 
755 /**
756  * \brief get stream for a PCM handle
757  * \param pcm PCM handle
758  * \return stream of PCM handle
759  *
760  * Returns the type #snd_pcm_stream_t of given PCM handle.
761  */
snd_pcm_stream(snd_pcm_t *pcm)762 snd_pcm_stream_t snd_pcm_stream(snd_pcm_t *pcm)
763 {
764 	assert(pcm);
765 	return pcm->stream;
766 }
767 
768 /**
769  * \brief close PCM handle
770  * \param pcm PCM handle
771  * \return 0 on success otherwise a negative error code
772  *
773  * Closes the specified PCM handle and frees all associated
774  * resources.
775  */
snd_pcm_close(snd_pcm_t *pcm)776 int snd_pcm_close(snd_pcm_t *pcm)
777 {
778 	int res = 0, err;
779 	assert(pcm);
780 	if (pcm->setup && !pcm->donot_close) {
781 		snd_pcm_drop(pcm);
782 		err = snd_pcm_hw_free(pcm);
783 		if (err < 0)
784 			res = err;
785 	}
786 	if (pcm->mmap_channels)
787 		snd_pcm_munmap(pcm);
788 	while (!list_empty(&pcm->async_handlers)) {
789 		snd_async_handler_t *h = list_entry(pcm->async_handlers.next, snd_async_handler_t, hlist);
790 		snd_async_del_handler(h);
791 	}
792 	if (pcm->ops->close)
793 		err = pcm->ops->close(pcm->op_arg);
794 	else
795 		err = -ENOSYS;
796 	if (err < 0)
797 		res = err;
798 	err = snd_pcm_free(pcm);
799 	if (err < 0)
800 		res = err;
801 	return res;
802 }
803 
804 /**
805  * \brief set nonblock mode
806  * \param pcm PCM handle
807  * \param nonblock 0 = block, 1 = nonblock mode, 2 = abort
808  * \return 0 on success otherwise a negative error code
809  *
810  * The function is thread-safe when built with the proper option.
811  */
snd_pcm_nonblock(snd_pcm_t *pcm, int nonblock)812 int snd_pcm_nonblock(snd_pcm_t *pcm, int nonblock)
813 {
814 	int err = 0;
815 
816 	assert(pcm);
817 	/* FIXME: __snd_pcm_lock() call below is commented out because of the
818 	 * the possible deadlock in signal handler calling snd_pcm_abort()
819 	 */
820 	/* __snd_pcm_lock(pcm->op_arg); */ /* forced lock due to pcm field change */
821 	if (pcm->ops->nonblock)
822 		err = pcm->ops->nonblock(pcm->op_arg, nonblock);
823 	else
824 		err = -ENOSYS;
825 	if (err < 0)
826 		goto unlock;
827 	if (nonblock == 2) {
828 		pcm->mode |= SND_PCM_ABORT;
829 		goto unlock;
830 	}
831 	if (nonblock)
832 		pcm->mode |= SND_PCM_NONBLOCK;
833 	else {
834 		if (pcm->hw_flags & SND_PCM_HW_PARAMS_NO_PERIOD_WAKEUP)
835 			err = -EINVAL;
836 		else
837 			pcm->mode &= ~SND_PCM_NONBLOCK;
838 	}
839  unlock:
840 	/* __snd_pcm_unlock(pcm->op_arg); */ /* FIXME: see above */
841 	return err;
842 }
843 
844 #ifndef DOC_HIDDEN
845 /**
846  * \brief set async mode
847  * \param pcm PCM handle
848  * \param sig Signal to raise: < 0 disable, 0 default (SIGIO)
849  * \param pid Process ID to signal: 0 current
850  * \return 0 on success otherwise a negative error code
851  *
852  * A signal is raised every period.
853  */
snd_pcm_async(snd_pcm_t *pcm, int sig, pid_t pid)854 int snd_pcm_async(snd_pcm_t *pcm, int sig, pid_t pid)
855 {
856 	int err = 0;
857 
858 	assert(pcm);
859 	if (sig == 0)
860 		sig = SIGIO;
861 	if (pid == 0)
862 		pid = getpid();
863 
864 #ifdef THREAD_SAFE_API
865 	/* async handler may lead to a deadlock; suppose no multi thread */
866 	pcm->lock_enabled = 0;
867 #endif
868 	if (pcm->ops->async)
869 		err = pcm->ops->async(pcm->op_arg, sig, pid);
870 	else
871 		err = -ENOSYS;
872 	return err;
873 }
874 #endif
875 
876 /**
877  * \brief Obtain general (static) information for PCM handle
878  * \param pcm PCM handle
879  * \param info Information container
880  * \return 0 on success otherwise a negative error code
881  */
snd_pcm_info(snd_pcm_t *pcm, snd_pcm_info_t *info)882 int snd_pcm_info(snd_pcm_t *pcm, snd_pcm_info_t *info)
883 {
884 	int err = 0;
885 
886 	assert(pcm && info);
887 	if (pcm->ops->info)
888 		err = pcm->ops->info(pcm->op_arg, info);
889 	else
890 		err = -ENOSYS;
891 	return err;
892 }
893 
894 /** \brief Retreive current PCM hardware configuration chosen with #snd_pcm_hw_params
895  * \param pcm PCM handle
896  * \param params Configuration space definition container
897  * \return 0 on success otherwise a negative error code
898  * \retval -EBADFD no hardware configuration is set
899  */
snd_pcm_hw_params_current(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)900 int snd_pcm_hw_params_current(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
901 {
902 	unsigned int frame_bits;
903 
904 	assert(pcm && params);
905 	if (!pcm->setup)
906 		return -EBADFD;
907 	memset(params, 0, snd_pcm_hw_params_sizeof());
908 	params->flags = pcm->hw_flags;
909 	snd_mask_set(&params->masks[SND_PCM_HW_PARAM_ACCESS - SND_PCM_HW_PARAM_FIRST_MASK], pcm->access);
910 	snd_mask_set(&params->masks[SND_PCM_HW_PARAM_FORMAT - SND_PCM_HW_PARAM_FIRST_MASK], pcm->format);
911 	snd_mask_set(&params->masks[SND_PCM_HW_PARAM_SUBFORMAT - SND_PCM_HW_PARAM_FIRST_MASK], pcm->subformat);
912 	frame_bits = snd_pcm_format_physical_width(pcm->format) * pcm->channels;
913 	snd_interval_set_value(&params->intervals[SND_PCM_HW_PARAM_FRAME_BITS - SND_PCM_HW_PARAM_FIRST_INTERVAL], frame_bits);
914 	snd_interval_set_value(&params->intervals[SND_PCM_HW_PARAM_CHANNELS - SND_PCM_HW_PARAM_FIRST_INTERVAL], pcm->channels);
915 	snd_interval_set_value(&params->intervals[SND_PCM_HW_PARAM_RATE - SND_PCM_HW_PARAM_FIRST_INTERVAL], pcm->rate);
916 	snd_interval_set_value(&params->intervals[SND_PCM_HW_PARAM_PERIOD_TIME - SND_PCM_HW_PARAM_FIRST_INTERVAL], pcm->period_time);
917 	snd_interval_set_value(&params->intervals[SND_PCM_HW_PARAM_PERIOD_SIZE - SND_PCM_HW_PARAM_FIRST_INTERVAL], pcm->period_size);
918 	snd_interval_copy(&params->intervals[SND_PCM_HW_PARAM_PERIODS - SND_PCM_HW_PARAM_FIRST_INTERVAL], &pcm->periods);
919 	snd_interval_copy(&params->intervals[SND_PCM_HW_PARAM_BUFFER_TIME - SND_PCM_HW_PARAM_FIRST_INTERVAL], &pcm->buffer_time);
920 	snd_interval_set_value(&params->intervals[SND_PCM_HW_PARAM_BUFFER_SIZE - SND_PCM_HW_PARAM_FIRST_INTERVAL], pcm->buffer_size);
921 	snd_interval_set_value(&params->intervals[SND_PCM_HW_PARAM_BUFFER_BYTES - SND_PCM_HW_PARAM_FIRST_INTERVAL], (pcm->buffer_size * frame_bits) / 8);
922 	params->info = pcm->info;
923 	params->msbits = pcm->msbits;
924 	params->rate_num = pcm->rate_num;
925 	params->rate_den = pcm->rate_den;
926 	params->fifo_size = pcm->fifo_size;
927 	return 0;
928 }
929 
930 /** \brief Install one PCM hardware configuration chosen from a configuration space and #snd_pcm_prepare it
931  * \param pcm PCM handle
932  * \param params Configuration space definition container
933  * \return 0 on success otherwise a negative error code
934  *
935  * The configuration is chosen fixing single parameters in this order:
936  * first access, first format, first subformat, min channels, min rate,
937  * min period time, max buffer size, min tick time. If no mutually
938  * compatible set of parameters can be chosen, a negative error code
939  * will be returned.
940  *
941  * After this call, #snd_pcm_prepare() is called automatically and
942  * the stream is brought to \c #SND_PCM_STATE_PREPARED state.
943  *
944  * The hardware parameters cannot be changed when the stream is
945  * running (active). The software parameters can be changed
946  * at any time.
947  *
948  * The configuration space will be updated to reflect the chosen
949  * parameters.
950  */
snd_pcm_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)951 int snd_pcm_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
952 {
953 	int err;
954 	assert(pcm && params);
955 	err = _snd_pcm_hw_params_internal(pcm, params);
956 	if (err < 0)
957 		return err;
958 	err = snd_pcm_prepare(pcm);
959 	return err;
960 }
961 
962 /** \brief Remove PCM hardware configuration and free associated resources
963  * \param pcm PCM handle
964  * \return 0 on success otherwise a negative error code
965  *
966  * The function will also report success if no configuration is set.
967  */
snd_pcm_hw_free(snd_pcm_t *pcm)968 int snd_pcm_hw_free(snd_pcm_t *pcm)
969 {
970 	int err;
971 	if (! pcm->setup)
972 		return 0;
973 	if (pcm->mmap_channels) {
974 		err = snd_pcm_munmap(pcm);
975 		if (err < 0)
976 			return err;
977 	}
978 	// assert(snd_pcm_state(pcm) == SND_PCM_STATE_SETUP ||
979 	//        snd_pcm_state(pcm) == SND_PCM_STATE_PREPARED);
980 	if (pcm->ops->hw_free)
981 		err = pcm->ops->hw_free(pcm->op_arg);
982 	else
983 		err = -ENOSYS;
984 	pcm->setup = 0;
985 	if (err < 0)
986 		return err;
987 	return 0;
988 }
989 
990 /** \brief Install PCM software configuration defined by params
991  * \param pcm PCM handle
992  * \param params Configuration container
993  * \return 0 on success otherwise a negative error code
994  *
995  * The software parameters can be changed at any time.
996  * The hardware parameters cannot be changed when the stream is
997  * running (active).
998  *
999  * The function is thread-safe when built with the proper option.
1000  */
snd_pcm_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t *params)1001 int snd_pcm_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t *params)
1002 {
1003 	int err;
1004 	/* the hw_params must be set at first!!! */
1005 	if (CHECK_SANITY(! pcm->setup)) {
1006 		SNDMSG("PCM not set up");
1007 		return -EIO;
1008 	}
1009 	if (! params->avail_min) {
1010 		SNDMSG("params->avail_min is 0");
1011 		return -EINVAL;
1012 	}
1013 #if 0
1014 	/* disable the check below - it looks too restrictive
1015 	 * (start_threshold is basically independent from avail_min)
1016 	 */
1017 	if (params->start_threshold <= pcm->buffer_size &&
1018 	    params->start_threshold > (pcm->buffer_size / params->avail_min) * params->avail_min) {
1019 		SNDMSG("params->avail_min problem for start_threshold");
1020 		return -EINVAL;
1021 	}
1022 #endif
1023 	__snd_pcm_lock(pcm->op_arg); /* forced lock due to pcm field change */
1024 	if (pcm->ops->sw_params)
1025 		err = pcm->ops->sw_params(pcm->op_arg, params);
1026 	else
1027 		err = -ENOSYS;
1028 	if (err < 0) {
1029 		__snd_pcm_unlock(pcm->op_arg);
1030 		return err;
1031 	}
1032 	pcm->tstamp_mode = params->tstamp_mode;
1033 	pcm->tstamp_type = params->tstamp_type;
1034 	pcm->period_step = params->period_step;
1035 	pcm->avail_min = params->avail_min;
1036 	pcm->period_event = sw_get_period_event(params);
1037 	pcm->start_threshold = params->start_threshold;
1038 	pcm->stop_threshold = params->stop_threshold;
1039 	pcm->silence_threshold = params->silence_threshold;
1040 	pcm->silence_size = params->silence_size;
1041 	pcm->boundary = params->boundary;
1042 	__snd_pcm_unlock(pcm->op_arg);
1043 	return 0;
1044 }
1045 
1046 /**
1047  * \brief Obtain status (runtime) information for PCM handle
1048  * \param pcm PCM handle
1049  * \param status Status container
1050  * \return 0 on success otherwise a negative error code
1051  *
1052  * The function is thread-safe when built with the proper option.
1053  */
snd_pcm_status(snd_pcm_t *pcm, snd_pcm_status_t *status)1054 int snd_pcm_status(snd_pcm_t *pcm, snd_pcm_status_t *status)
1055 {
1056 	int err;
1057 
1058 	assert(pcm && status);
1059 	snd_pcm_lock(pcm->fast_op_arg);
1060 	if (pcm->fast_ops->status)
1061 		err = pcm->fast_ops->status(pcm->fast_op_arg, status);
1062 	else
1063 		err = -ENOSYS;
1064 	snd_pcm_unlock(pcm->fast_op_arg);
1065 
1066 	return err;
1067 }
1068 
1069 /**
1070  * \brief Return PCM state
1071  * \param pcm PCM handle
1072  * \return PCM state #snd_pcm_state_t of given PCM handle
1073  *
1074  * This is a faster way to obtain only the PCM state without calling
1075  * \link ::snd_pcm_status() \endlink.
1076  *
1077  * Note that this function always returns one of the
1078  * #snd_pcm_state_t enum variants.
1079  * It will never return a negative error code.
1080  *
1081  * The function is thread-safe when built with the proper option.
1082  */
snd_pcm_state(snd_pcm_t *pcm)1083 snd_pcm_state_t snd_pcm_state(snd_pcm_t *pcm)
1084 {
1085 	snd_pcm_state_t state;
1086 
1087 	assert(pcm);
1088 	snd_pcm_lock(pcm->fast_op_arg);
1089 	state = __snd_pcm_state(pcm);
1090 	snd_pcm_unlock(pcm->fast_op_arg);
1091 	return state;
1092 }
1093 
1094 /**
1095  * \brief (DEPRECATED) Synchronize stream position with hardware
1096  * \param pcm PCM handle
1097  * \return 0 on success otherwise a negative error code
1098  *
1099  * Note this function does not update the actual r/w pointer
1100  * for applications. The function #snd_pcm_avail_update()
1101  * have to be called before any mmap begin+commit operation.
1102  *
1103  * The function is thread-safe when built with the proper option.
1104  *
1105  * This function is deprecated. Use #snd_pcm_avail_update() instead.
1106  */
snd_pcm_hwsync(snd_pcm_t *pcm)1107 int snd_pcm_hwsync(snd_pcm_t *pcm)
1108 {
1109 	int err;
1110 
1111 	assert(pcm);
1112 	if (CHECK_SANITY(! pcm->setup)) {
1113 		SNDMSG("PCM not set up");
1114 		return -EIO;
1115 	}
1116 	snd_pcm_lock(pcm->fast_op_arg);
1117 	err = __snd_pcm_hwsync(pcm);
1118 	snd_pcm_unlock(pcm->fast_op_arg);
1119 	return err;
1120 }
1121 
1122 /**
1123  * \brief Obtain delay for a running PCM handle
1124  * \param pcm PCM handle
1125  * \param delayp Returned delay in frames
1126  * \return 0 on success otherwise a negative error code
1127  *
1128  * For playback the delay is defined as the time that a frame that is written
1129  * to the PCM stream shortly after this call will take to be actually
1130  * audible. It is as such the overall latency from the write call to the final
1131  * DAC.
1132  *
1133  * For capture the delay is defined as the time that a frame that was
1134  * digitized by the audio device takes until it can be read from the PCM
1135  * stream shortly after this call returns. It is as such the overall latency
1136  * from the initial ADC to the read call.
1137  *
1138  * Please note that hence in case of a playback underrun this value will not
1139  * necessarily got down to 0.
1140  *
1141  * If the application is interested in the fill level of the playback buffer
1142  * of the device, it should use #snd_pcm_avail*() functions. The
1143  * value returned by that call is not directly related to the delay, since the
1144  * latter might include some additional, fixed latencies the former does not.
1145  *
1146  * Note this function does not update the actual r/w pointer
1147  * for applications. The function #snd_pcm_avail_update()
1148  * have to be called before any begin+commit operation.
1149  *
1150  * The function is thread-safe when built with the proper option.
1151  */
snd_pcm_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp)1152 int snd_pcm_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp)
1153 {
1154 	int err;
1155 
1156 	assert(pcm);
1157 	if (CHECK_SANITY(! pcm->setup)) {
1158 		SNDMSG("PCM not set up");
1159 		return -EIO;
1160 	}
1161 	snd_pcm_lock(pcm->fast_op_arg);
1162 	err = __snd_pcm_delay(pcm, delayp);
1163 	snd_pcm_unlock(pcm->fast_op_arg);
1164 	return err;
1165 }
1166 
1167 /**
1168  * \brief Resume from suspend, no samples are lost
1169  * \param pcm PCM handle
1170  * \return 0 on success otherwise a negative error code
1171  * \retval -EAGAIN resume can't be proceed immediately (audio hardware is probably still suspended)
1172  * \retval -ENOSYS hardware doesn't support this feature
1173  *
1174  * This function can be used when the stream is in the suspend state
1175  * to do the fine resume from this state. Not all hardware supports
1176  * this feature, when an -ENOSYS error is returned, use the \link ::snd_pcm_prepare() \endlink
1177  * function to recovery.
1178  *
1179  * The function is thread-safe when built with the proper option.
1180  */
snd_pcm_resume(snd_pcm_t *pcm)1181 int snd_pcm_resume(snd_pcm_t *pcm)
1182 {
1183 	int err = 0;
1184 
1185 	assert(pcm);
1186 	if (CHECK_SANITY(! pcm->setup)) {
1187 		SNDMSG("PCM not set up");
1188 		return -EIO;
1189 	}
1190 	/* lock handled in the callback */
1191 	if (pcm->fast_ops->resume)
1192 		err = pcm->fast_ops->resume(pcm->fast_op_arg);
1193 	else
1194 		err = -ENOSYS;
1195 	return err;
1196 }
1197 
1198 /**
1199  * \brief Obtain last position update hi-res timestamp
1200  * \param pcm PCM handle
1201  * \param avail Number of available frames when timestamp was grabbed
1202  * \param tstamp Hi-res timestamp
1203  * \return 0 on success otherwise a negative error code
1204  *
1205  * Note this function does not update the actual r/w pointer
1206  * for applications.
1207  *
1208  * The function is thread-safe when built with the proper option.
1209  */
snd_pcm_htimestamp(snd_pcm_t *pcm, snd_pcm_uframes_t *avail, snd_htimestamp_t *tstamp)1210 int snd_pcm_htimestamp(snd_pcm_t *pcm, snd_pcm_uframes_t *avail, snd_htimestamp_t *tstamp)
1211 {
1212 	int err;
1213 
1214 	assert(pcm);
1215 	if (CHECK_SANITY(! pcm->setup)) {
1216 		SNDMSG("PCM not set up");
1217 		return -EIO;
1218 	}
1219 	snd_pcm_lock(pcm->fast_op_arg);
1220 	if (pcm->fast_ops->htimestamp)
1221 		err = pcm->fast_ops->htimestamp(pcm->fast_op_arg, avail, tstamp);
1222 	else
1223 		err = -ENOSYS;
1224 	snd_pcm_unlock(pcm->fast_op_arg);
1225 	return err;
1226 }
1227 
1228 /**
1229  * \brief Prepare PCM for use
1230  * \param pcm PCM handle
1231  * \return 0 on success otherwise a negative error code
1232  *
1233  * The function is thread-safe when built with the proper option.
1234  */
snd_pcm_prepare(snd_pcm_t *pcm)1235 int snd_pcm_prepare(snd_pcm_t *pcm)
1236 {
1237 	int err;
1238 
1239 	assert(pcm);
1240 	if (CHECK_SANITY(! pcm->setup)) {
1241 		SNDMSG("PCM not set up");
1242 		return -EIO;
1243 	}
1244 	err = bad_pcm_state(pcm, ~P_STATE(DISCONNECTED), 0);
1245 	if (err < 0)
1246 		return err;
1247 	snd_pcm_lock(pcm->fast_op_arg);
1248 	if (pcm->fast_ops->prepare)
1249 		err = pcm->fast_ops->prepare(pcm->fast_op_arg);
1250 	else
1251 		err = -ENOSYS;
1252 	snd_pcm_unlock(pcm->fast_op_arg);
1253 	return err;
1254 }
1255 
1256 /**
1257  * \brief Reset PCM position
1258  * \param pcm PCM handle
1259  * \return 0 on success otherwise a negative error code
1260  *
1261  * Reduce PCM delay to 0.
1262  *
1263  * The function is thread-safe when built with the proper option.
1264  */
snd_pcm_reset(snd_pcm_t *pcm)1265 int snd_pcm_reset(snd_pcm_t *pcm)
1266 {
1267 	int err;
1268 
1269 	assert(pcm);
1270 	if (CHECK_SANITY(! pcm->setup)) {
1271 		SNDMSG("PCM not set up");
1272 		return -EIO;
1273 	}
1274 	snd_pcm_lock(pcm->fast_op_arg);
1275 	if (pcm->fast_ops->reset)
1276 		err = pcm->fast_ops->reset(pcm->fast_op_arg);
1277 	else
1278 		err = -ENOSYS;
1279 	snd_pcm_unlock(pcm->fast_op_arg);
1280 	return err;
1281 }
1282 
1283 /**
1284  * \brief Start a PCM
1285  * \param pcm PCM handle
1286  * \return 0 on success otherwise a negative error code
1287  *
1288  * The function is thread-safe when built with the proper option.
1289  */
snd_pcm_start(snd_pcm_t *pcm)1290 int snd_pcm_start(snd_pcm_t *pcm)
1291 {
1292 	int err;
1293 
1294 	assert(pcm);
1295 	if (CHECK_SANITY(! pcm->setup)) {
1296 		SNDMSG("PCM not set up");
1297 		return -EIO;
1298 	}
1299 	err = bad_pcm_state(pcm, P_STATE(PREPARED), 0);
1300 	if (err < 0)
1301 		return err;
1302 	snd_pcm_lock(pcm->fast_op_arg);
1303 	err = __snd_pcm_start(pcm);
1304 	snd_pcm_unlock(pcm->fast_op_arg);
1305 	return err;
1306 }
1307 
1308 /**
1309  * \brief Stop a PCM dropping pending frames
1310  * \param pcm PCM handle
1311  * \return 0 on success otherwise a negative error code
1312  *
1313  * This function stops the PCM <i>immediately</i>.
1314  * The pending samples on the buffer are ignored.
1315  *
1316  * For processing all pending samples, use \link ::snd_pcm_drain() \endlink
1317  * instead.
1318  *
1319  * The function is thread-safe when built with the proper option.
1320  */
snd_pcm_drop(snd_pcm_t *pcm)1321 int snd_pcm_drop(snd_pcm_t *pcm)
1322 {
1323 	int err;
1324 
1325 	assert(pcm);
1326 	if (CHECK_SANITY(! pcm->setup)) {
1327 		SNDMSG("PCM not set up");
1328 		return -EIO;
1329 	}
1330 	err = bad_pcm_state(pcm, P_STATE_RUNNABLE | P_STATE(SETUP) |
1331 			    P_STATE(SUSPENDED), 0);
1332 	if (err < 0)
1333 		return err;
1334 	snd_pcm_lock(pcm->fast_op_arg);
1335 	if (pcm->fast_ops->drop)
1336 		err = pcm->fast_ops->drop(pcm->fast_op_arg);
1337 	else
1338 		err = -ENOSYS;
1339 	snd_pcm_unlock(pcm->fast_op_arg);
1340 	return err;
1341 }
1342 
1343 /**
1344  * \brief Stop a PCM preserving pending frames
1345  * \param pcm PCM handle
1346  * \return 0 on success otherwise a negative error code
1347  * \retval -ESTRPIPE a suspend event occurred
1348  *
1349  * For playback wait for all pending frames to be played and then stop
1350  * the PCM.
1351  * For capture stop PCM permitting to retrieve residual frames.
1352  *
1353  * For stopping the PCM stream immediately, use \link ::snd_pcm_drop() \endlink
1354  * instead.
1355  *
1356  * The function is thread-safe when built with the proper option.
1357  */
snd_pcm_drain(snd_pcm_t *pcm)1358 int snd_pcm_drain(snd_pcm_t *pcm)
1359 {
1360 	int err;
1361 
1362 	assert(pcm);
1363 	if (CHECK_SANITY(! pcm->setup)) {
1364 		SNDMSG("PCM not set up");
1365 		return -EIO;
1366 	}
1367 	err = bad_pcm_state(pcm, P_STATE_RUNNABLE | P_STATE(SETUP), P_STATE(SETUP));
1368 	if (err < 0)
1369 		return err;
1370 	if (err == 1)
1371 		return 0;
1372 	/* lock handled in the callback */
1373 	if (pcm->fast_ops->drain)
1374 		err = pcm->fast_ops->drain(pcm->fast_op_arg);
1375 	else
1376 		err = -ENOSYS;
1377 	return err;
1378 }
1379 
1380 /**
1381  * \brief Pause/resume PCM
1382  * \param pcm PCM handle
1383  * \param enable 0 = resume, 1 = pause
1384  * \return 0 on success otherwise a negative error code
1385  *
1386  * Note that this function works only on the hardware which supports
1387  * pause feature.  You can check it via \link ::snd_pcm_hw_params_can_pause() \endlink
1388  * function.
1389  *
1390  * The function is thread-safe when built with the proper option.
1391  */
snd_pcm_pause(snd_pcm_t *pcm, int enable)1392 int snd_pcm_pause(snd_pcm_t *pcm, int enable)
1393 {
1394 	int err;
1395 
1396 	assert(pcm);
1397 	if (CHECK_SANITY(! pcm->setup)) {
1398 		SNDMSG("PCM not set up");
1399 		return -EIO;
1400 	}
1401 	err = bad_pcm_state(pcm, P_STATE_RUNNABLE, 0);
1402 	if (err < 0)
1403 		return err;
1404 	snd_pcm_lock(pcm->fast_op_arg);
1405 	if (pcm->fast_ops->pause)
1406 		err = pcm->fast_ops->pause(pcm->fast_op_arg, enable);
1407 	else
1408 		err = -ENOSYS;
1409 	snd_pcm_unlock(pcm->fast_op_arg);
1410 	return err;
1411 }
1412 
1413 /**
1414  * \brief Get safe count of frames which can be rewinded
1415  * \param pcm PCM handle
1416  * \return a positive number of frames or negative error code
1417  *
1418  * Note: The snd_pcm_rewind() can accept bigger value than returned
1419  * by this function. But it is not guaranteed that output stream
1420  * will be consistent with bigger value.
1421  *
1422  * The function is thread-safe when built with the proper option.
1423  */
snd_pcm_rewindable(snd_pcm_t *pcm)1424 snd_pcm_sframes_t snd_pcm_rewindable(snd_pcm_t *pcm)
1425 {
1426 	snd_pcm_sframes_t result;
1427 	int err;
1428 
1429 	assert(pcm);
1430 	if (CHECK_SANITY(! pcm->setup)) {
1431 		SNDMSG("PCM not set up");
1432 		return -EIO;
1433 	}
1434 	err = bad_pcm_state(pcm, P_STATE_RUNNABLE, 0);
1435 	if (err < 0)
1436 		return err;
1437 	snd_pcm_lock(pcm->fast_op_arg);
1438 	if (pcm->fast_ops->rewindable)
1439 		result = pcm->fast_ops->rewindable(pcm->fast_op_arg);
1440 	else
1441 		result = -ENOSYS;
1442 	snd_pcm_unlock(pcm->fast_op_arg);
1443 	return result;
1444 }
1445 
1446 /**
1447  * \brief Move application frame position backward
1448  * \param pcm PCM handle
1449  * \param frames wanted displacement in frames
1450  * \return a positive number for actual displacement otherwise a
1451  * negative error code
1452  *
1453  * The function is thread-safe when built with the proper option.
1454  */
snd_pcm_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames)1455 snd_pcm_sframes_t snd_pcm_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
1456 {
1457 	snd_pcm_sframes_t result;
1458 	int err;
1459 
1460 	assert(pcm);
1461 	if (CHECK_SANITY(! pcm->setup)) {
1462 		SNDMSG("PCM not set up");
1463 		return -EIO;
1464 	}
1465 	if (frames == 0)
1466 		return 0;
1467 	err = bad_pcm_state(pcm, P_STATE_RUNNABLE, 0);
1468 	if (err < 0)
1469 		return err;
1470 	snd_pcm_lock(pcm->fast_op_arg);
1471 	if (pcm->fast_ops->rewind)
1472 		result = pcm->fast_ops->rewind(pcm->fast_op_arg, frames);
1473 	else
1474 		result = -ENOSYS;
1475 	snd_pcm_unlock(pcm->fast_op_arg);
1476 	return result;
1477 }
1478 
1479 /**
1480  * \brief Get safe count of frames which can be forwarded
1481  * \param pcm PCM handle
1482  * \return a positive number of frames or negative error code
1483  *
1484  * Note: The snd_pcm_forward() can accept bigger value than returned
1485  * by this function. But it is not guaranteed that output stream
1486  * will be consistent with bigger value.
1487  *
1488  * The function is thread-safe when built with the proper option.
1489  */
snd_pcm_forwardable(snd_pcm_t *pcm)1490 snd_pcm_sframes_t snd_pcm_forwardable(snd_pcm_t *pcm)
1491 {
1492 	snd_pcm_sframes_t result;
1493 	int err;
1494 
1495 	assert(pcm);
1496 	if (CHECK_SANITY(! pcm->setup)) {
1497 		SNDMSG("PCM not set up");
1498 		return -EIO;
1499 	}
1500 	err = bad_pcm_state(pcm, P_STATE_RUNNABLE, 0);
1501 	if (err < 0)
1502 		return err;
1503 	snd_pcm_lock(pcm->fast_op_arg);
1504 	if (pcm->fast_ops->forwardable)
1505 		result = pcm->fast_ops->forwardable(pcm->fast_op_arg);
1506 	else
1507 		result = -ENOSYS;
1508 	snd_pcm_unlock(pcm->fast_op_arg);
1509 	return result;
1510 }
1511 
1512 /**
1513  * \brief Move application frame position forward
1514  * \param pcm PCM handle
1515  * \param frames wanted skip in frames
1516  * \return a positive number for actual skip otherwise a negative error code
1517  * \retval 0 means no action
1518  *
1519  * The function is thread-safe when built with the proper option.
1520  */
1521 #ifndef DOXYGEN
snd_pcm_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames)1522 EXPORT_SYMBOL snd_pcm_sframes_t INTERNAL(snd_pcm_forward)(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
1523 #else
1524 snd_pcm_sframes_t snd_pcm_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
1525 #endif
1526 {
1527 	snd_pcm_sframes_t result;
1528 	int err;
1529 
1530 	assert(pcm);
1531 	if (CHECK_SANITY(! pcm->setup)) {
1532 		SNDMSG("PCM not set up");
1533 		return -EIO;
1534 	}
1535 	if (frames == 0)
1536 		return 0;
1537 	err = bad_pcm_state(pcm, P_STATE_RUNNABLE, 0);
1538 	if (err < 0)
1539 		return err;
1540 	snd_pcm_lock(pcm->fast_op_arg);
1541 	if (pcm->fast_ops->forward)
1542 		result = pcm->fast_ops->forward(pcm->fast_op_arg, frames);
1543 	else
1544 		result = -ENOSYS;
1545 	snd_pcm_unlock(pcm->fast_op_arg);
1546 	return result;
1547 }
1548 use_default_symbol_version(__snd_pcm_forward, snd_pcm_forward, ALSA_0.9.0rc8);
1549 
1550 /**
1551  * \brief Write interleaved frames to a PCM
1552  * \param pcm PCM handle
1553  * \param buffer frames containing buffer
1554  * \param size frames to be written
1555  * \return a positive number of frames actually written otherwise a
1556  * negative error code
1557  * \retval -EBADFD PCM is not in the right state (#SND_PCM_STATE_PREPARED or #SND_PCM_STATE_RUNNING)
1558  * \retval -EPIPE an underrun occurred
1559  * \retval -ESTRPIPE a suspend event occurred (stream is suspended and waiting for an application recovery)
1560  *
1561  * If the blocking behaviour is selected and it is running, then routine waits until
1562  * all requested frames are played or put to the playback ring buffer.
1563  * The returned number of frames can be less only if a signal or underrun occurred.
1564  *
1565  * If the non-blocking behaviour is selected, then routine doesn't wait at all.
1566  *
1567  * The function is thread-safe when built with the proper option.
1568  */
snd_pcm_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size)1569 snd_pcm_sframes_t snd_pcm_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size)
1570 {
1571 	int err;
1572 
1573 	assert(pcm);
1574 	assert(size == 0 || buffer);
1575 	if (CHECK_SANITY(! pcm->setup)) {
1576 		SNDMSG("PCM not set up");
1577 		return -EIO;
1578 	}
1579 	if (pcm->access != SND_PCM_ACCESS_RW_INTERLEAVED) {
1580 		SNDMSG("invalid access type %s", snd_pcm_access_name(pcm->access));
1581 		return -EINVAL;
1582 	}
1583 	err = bad_pcm_state(pcm, P_STATE_RUNNABLE, 0);
1584 	if (err < 0)
1585 		return err;
1586 	return _snd_pcm_writei(pcm, buffer, size);
1587 }
1588 
1589 /**
1590  * \brief Write non interleaved frames to a PCM
1591  * \param pcm PCM handle
1592  * \param bufs frames containing buffers (one for each channel)
1593  * \param size frames to be written
1594  * \return a positive number of frames actually written otherwise a
1595  * negative error code
1596  * \retval -EBADFD PCM is not in the right state (#SND_PCM_STATE_PREPARED or #SND_PCM_STATE_RUNNING)
1597  * \retval -EPIPE an underrun occurred
1598  * \retval -ESTRPIPE a suspend event occurred (stream is suspended and waiting for an application recovery)
1599  *
1600  * If the blocking behaviour is selected and it is running, then routine waits until
1601  * all requested frames are played or put to the playback ring buffer.
1602  * The returned number of frames can be less only if a signal or underrun occurred.
1603  *
1604  * If the non-blocking behaviour is selected, then routine doesn't wait at all.
1605  *
1606  * The function is thread-safe when built with the proper option.
1607  */
snd_pcm_writen(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size)1608 snd_pcm_sframes_t snd_pcm_writen(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size)
1609 {
1610 	int err;
1611 
1612 	assert(pcm);
1613 	assert(size == 0 || bufs);
1614 	if (CHECK_SANITY(! pcm->setup)) {
1615 		SNDMSG("PCM not set up");
1616 		return -EIO;
1617 	}
1618 	if (pcm->access != SND_PCM_ACCESS_RW_NONINTERLEAVED) {
1619 		SNDMSG("invalid access type %s", snd_pcm_access_name(pcm->access));
1620 		return -EINVAL;
1621 	}
1622 	err = bad_pcm_state(pcm, P_STATE_RUNNABLE, 0);
1623 	if (err < 0)
1624 		return err;
1625 	return _snd_pcm_writen(pcm, bufs, size);
1626 }
1627 
1628 /**
1629  * \brief Read interleaved frames from a PCM
1630  * \param pcm PCM handle
1631  * \param buffer frames containing buffer
1632  * \param size frames to be read
1633  * \return a positive number of frames actually read otherwise a
1634  * negative error code
1635  * \retval -EBADFD PCM is not in the right state (#SND_PCM_STATE_PREPARED or #SND_PCM_STATE_RUNNING)
1636  * \retval -EPIPE an overrun occurred
1637  * \retval -ESTRPIPE a suspend event occurred (stream is suspended and waiting for an application recovery)
1638  *
1639  * If the blocking behaviour was selected and it is running, then routine waits until
1640  * all requested frames are filled. The returned number of frames can be less only
1641  * if a signal or underrun occurred.
1642  *
1643  * If the non-blocking behaviour is selected, then routine doesn't wait at all.
1644  *
1645  * The function is thread-safe when built with the proper option.
1646  */
snd_pcm_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size)1647 snd_pcm_sframes_t snd_pcm_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size)
1648 {
1649 	int err;
1650 
1651 	assert(pcm);
1652 	assert(size == 0 || buffer);
1653 	if (CHECK_SANITY(! pcm->setup)) {
1654 		SNDMSG("PCM not set up");
1655 		return -EIO;
1656 	}
1657 	if (pcm->access != SND_PCM_ACCESS_RW_INTERLEAVED) {
1658 		SNDMSG("invalid access type %s", snd_pcm_access_name(pcm->access));
1659 		return -EINVAL;
1660 	}
1661 	err = bad_pcm_state(pcm, P_STATE_RUNNABLE, 0);
1662 	if (err < 0)
1663 		return err;
1664 	return _snd_pcm_readi(pcm, buffer, size);
1665 }
1666 
1667 /**
1668  * \brief Read non interleaved frames to a PCM
1669  * \param pcm PCM handle
1670  * \param bufs frames containing buffers (one for each channel)
1671  * \param size frames to be read
1672  * \return a positive number of frames actually read otherwise a
1673  * negative error code
1674  * \retval -EBADFD PCM is not in the right state (#SND_PCM_STATE_PREPARED or #SND_PCM_STATE_RUNNING)
1675  * \retval -EPIPE an overrun occurred
1676  * \retval -ESTRPIPE a suspend event occurred (stream is suspended and waiting for an application recovery)
1677  *
1678  * If the blocking behaviour was selected and it is running, then routine waits until
1679  * all requested frames are filled. The returned number of frames can be less only
1680  * if a signal or underrun occurred.
1681  *
1682  * If the non-blocking behaviour is selected, then routine doesn't wait at all.
1683  *
1684  * The function is thread-safe when built with the proper option.
1685  */
snd_pcm_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size)1686 snd_pcm_sframes_t snd_pcm_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size)
1687 {
1688 	int err;
1689 
1690 	assert(pcm);
1691 	assert(size == 0 || bufs);
1692 	if (CHECK_SANITY(! pcm->setup)) {
1693 		SNDMSG("PCM not set up");
1694 		return -EIO;
1695 	}
1696 	if (pcm->access != SND_PCM_ACCESS_RW_NONINTERLEAVED) {
1697 		SNDMSG("invalid access type %s", snd_pcm_access_name(pcm->access));
1698 		return -EINVAL;
1699 	}
1700 	err = bad_pcm_state(pcm, P_STATE_RUNNABLE, 0);
1701 	if (err < 0)
1702 		return err;
1703 	return _snd_pcm_readn(pcm, bufs, size);
1704 }
1705 
1706 /**
1707  * \brief Link two PCMs
1708  * \param pcm1 first PCM handle
1709  * \param pcm2 first PCM handle
1710  * \return 0 on success otherwise a negative error code
1711  *
1712  * The two PCMs will start/stop/prepare in sync.
1713  */
snd_pcm_link(snd_pcm_t *pcm1, snd_pcm_t *pcm2)1714 int snd_pcm_link(snd_pcm_t *pcm1, snd_pcm_t *pcm2)
1715 {
1716 	int err = 0;
1717 
1718 	assert(pcm1);
1719 	assert(pcm2);
1720 	if (pcm1->fast_ops->link)
1721 		err = pcm1->fast_ops->link(pcm1->fast_op_arg, pcm2);
1722 	else
1723 		err = -ENOSYS;
1724 	return err;
1725 }
1726 
1727 /**
1728  * \brief Remove a PCM from a linked group
1729  * \param pcm PCM handle
1730  * \return 0 on success otherwise a negative error code
1731  */
snd_pcm_unlink(snd_pcm_t *pcm)1732 int snd_pcm_unlink(snd_pcm_t *pcm)
1733 {
1734 	int err = 0;
1735 
1736 	assert(pcm);
1737 	if (pcm->fast_ops->unlink)
1738 		err = pcm->fast_ops->unlink(pcm->fast_op_arg);
1739 	else
1740 		err = -ENOSYS;
1741 	return err;
1742 }
1743 
1744 /* locked version */
__snd_pcm_poll_descriptors_count(snd_pcm_t *pcm)1745 static int __snd_pcm_poll_descriptors_count(snd_pcm_t *pcm)
1746 {
1747 	if (pcm->fast_ops->poll_descriptors_count)
1748 		return pcm->fast_ops->poll_descriptors_count(pcm->fast_op_arg);
1749 	return pcm->poll_fd_count;
1750 }
1751 
1752 /**
1753  * \brief get count of poll descriptors for PCM handle
1754  * \param pcm PCM handle
1755  * \return count of poll descriptors
1756  *
1757  * The function is thread-safe when built with the proper option.
1758  */
snd_pcm_poll_descriptors_count(snd_pcm_t *pcm)1759 int snd_pcm_poll_descriptors_count(snd_pcm_t *pcm)
1760 {
1761 	int count;
1762 
1763 	assert(pcm);
1764 	snd_pcm_lock(pcm->fast_op_arg);
1765 	count = __snd_pcm_poll_descriptors_count(pcm);
1766 	snd_pcm_unlock(pcm->fast_op_arg);
1767 	return count;
1768 }
1769 
1770 /* locked version */
__snd_pcm_poll_descriptors(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int space)1771 static int __snd_pcm_poll_descriptors(snd_pcm_t *pcm, struct pollfd *pfds,
1772 				      unsigned int space)
1773 {
1774 	if (pcm->fast_ops->poll_descriptors)
1775 		return pcm->fast_ops->poll_descriptors(pcm->fast_op_arg, pfds, space);
1776 	if (pcm->poll_fd < 0) {
1777 		SNDMSG("poll_fd < 0");
1778 		return -EIO;
1779 	}
1780 	if (space >= 1 && pfds) {
1781 		pfds->fd = pcm->poll_fd;
1782 		pfds->events = pcm->poll_events | POLLERR | POLLNVAL;
1783 	} else {
1784 		return 0;
1785 	}
1786 	return 1;
1787 }
1788 
1789 /**
1790  * \brief get poll descriptors
1791  * \param pcm PCM handle
1792  * \param pfds array of poll descriptors
1793  * \param space space in the poll descriptor array
1794  * \return count of filled descriptors
1795  *
1796  * This function fills the given poll descriptor structs for the specified
1797  * PCM handle.  The poll desctiptor array should have the size returned by
1798  * \link ::snd_pcm_poll_descriptors_count() \endlink function.
1799  *
1800  * The result is intended for direct use with the poll() syscall.
1801  *
1802  * For reading the returned events of poll descriptor after poll() system
1803  * call, use \link ::snd_pcm_poll_descriptors_revents() \endlink function.
1804  * The field values in pollfd structs may be bogus regarding the stream
1805  * direction from the application perspective (POLLIN might not imply read
1806  * direction and POLLOUT might not imply write), but
1807  * the \link ::snd_pcm_poll_descriptors_revents() \endlink function
1808  * does the right "demangling".
1809  *
1810  * You can use output from this function as arguments for the select()
1811  * syscall, too. Do not forget to translate POLLIN and POLLOUT events to
1812  * corresponding FD_SET arrays and demangle events using
1813  * \link ::snd_pcm_poll_descriptors_revents() \endlink .
1814  *
1815  * It is guaranteed that for the given PCM handle, the output poll
1816  * descriptor structs (and their count) will not change after
1817  * hardware and software parameters setup. Thus it is valid to call
1818  * the function once when all parameters are set and reuse its output
1819  * for the lifetime of the stream parameters.
1820  *
1821  * The function is thread-safe when built with the proper option.
1822  */
snd_pcm_poll_descriptors(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int space)1823 int snd_pcm_poll_descriptors(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int space)
1824 {
1825 	int err;
1826 
1827 	assert(pcm && pfds);
1828 	snd_pcm_lock(pcm->fast_op_arg);
1829 	err = __snd_pcm_poll_descriptors(pcm, pfds, space);
1830 	snd_pcm_unlock(pcm->fast_op_arg);
1831 	return err;
1832 }
1833 
1834 static int __snd_pcm_poll_revents(snd_pcm_t *pcm, struct pollfd *pfds,
1835 				  unsigned int nfds, unsigned short *revents);
1836 
1837 /**
1838  * \brief get returned events from poll descriptors
1839  * \param pcm PCM handle
1840  * \param pfds array of poll descriptors
1841  * \param nfds count of poll descriptors
1842  * \param revents pointer to the returned (single) event
1843  * \return zero if success, otherwise a negative error code
1844  *
1845  * This function does "demangling" of the revents mask returned from
1846  * the poll() syscall to correct semantics (POLLIN = read, POLLOUT = write).
1847  *
1848  * Note: The null event also exists. Even if poll() or select()
1849  * syscall returned that some events are waiting, this function might
1850  * return empty set of events. In this case, application should
1851  * do next event waiting using poll() or select().
1852  *
1853  * Note: Even if multiple poll descriptors are used (i.e. pfds > 1),
1854  * this function returns only a single event.
1855  *
1856  * The passed in count of poll descriptors must be equal to
1857  * \link ::snd_pcm_poll_descriptors_count() \endlink and the passed in array
1858  * must match the array returned by \link ::snd_pcm_poll_descriptors() \endlink
1859  * (in its full length and original order) with the revent fields updated
1860  * according to the poll() result. This function will not modify the file
1861  * descriptor or event field of any element of the given poll descriptor array.
1862  *
1863  * The function is thread-safe when built with the proper option.
1864  */
snd_pcm_poll_descriptors_revents(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int nfds, unsigned short *revents)1865 int snd_pcm_poll_descriptors_revents(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int nfds, unsigned short *revents)
1866 {
1867 	int err;
1868 
1869 	assert(pcm && pfds && revents);
1870 	snd_pcm_lock(pcm->fast_op_arg);
1871 	err = __snd_pcm_poll_revents(pcm, pfds, nfds, revents);
1872 	snd_pcm_unlock(pcm->fast_op_arg);
1873 	return err;
1874 }
1875 
__snd_pcm_poll_revents(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int nfds, unsigned short *revents)1876 static int __snd_pcm_poll_revents(snd_pcm_t *pcm, struct pollfd *pfds,
1877 				  unsigned int nfds, unsigned short *revents)
1878 {
1879 	if (pcm->fast_ops->poll_revents)
1880 		return pcm->fast_ops->poll_revents(pcm->fast_op_arg, pfds, nfds, revents);
1881 	if (nfds == 1) {
1882 		*revents = pfds->revents;
1883 		return 0;
1884 	}
1885 	return -EINVAL;
1886 }
1887 
1888 #ifndef DOC_HIDDEN
1889 #define PCMTYPE(v) [SND_PCM_TYPE_##v] = #v
1890 #define STATE(v) [SND_PCM_STATE_##v] = #v
1891 #define STREAM(v) [SND_PCM_STREAM_##v] = #v
1892 #define READY(v) [SND_PCM_READY_##v] = #v
1893 #define XRUN(v) [SND_PCM_XRUN_##v] = #v
1894 #define SILENCE(v) [SND_PCM_SILENCE_##v] = #v
1895 #define TSTAMP(v) [SND_PCM_TSTAMP_##v] = #v
1896 #define TSTAMP_TYPE(v) [SND_PCM_TSTAMP_TYPE_##v] = #v
1897 #define ACCESS(v) [SND_PCM_ACCESS_##v] = #v
1898 #define START(v) [SND_PCM_START_##v] = #v
1899 #define HW_PARAM(v) [SND_PCM_HW_PARAM_##v] = #v
1900 #define SW_PARAM(v) [SND_PCM_SW_PARAM_##v] = #v
1901 #define FORMAT(v) [SND_PCM_FORMAT_##v] = #v
1902 #define SUBFORMAT(v) [SND_PCM_SUBFORMAT_##v] = #v
1903 
1904 #define FORMATD(v, d) [SND_PCM_FORMAT_##v] = d
1905 #define SUBFORMATD(v, d) [SND_PCM_SUBFORMAT_##v] = d
1906 
1907 
1908 static const char *const snd_pcm_stream_names[] = {
1909 	STREAM(PLAYBACK),
1910 	STREAM(CAPTURE),
1911 };
1912 
1913 static const char *const snd_pcm_state_names[] = {
1914 	STATE(OPEN),
1915 	STATE(SETUP),
1916 	STATE(PREPARED),
1917 	STATE(RUNNING),
1918 	STATE(XRUN),
1919 	STATE(DRAINING),
1920 	STATE(PAUSED),
1921 	STATE(SUSPENDED),
1922 	STATE(DISCONNECTED),
1923 };
1924 
1925 static const char *const snd_pcm_access_names[] = {
1926 	ACCESS(MMAP_INTERLEAVED),
1927 	ACCESS(MMAP_NONINTERLEAVED),
1928 	ACCESS(MMAP_COMPLEX),
1929 	ACCESS(RW_INTERLEAVED),
1930 	ACCESS(RW_NONINTERLEAVED),
1931 };
1932 
1933 static const char *const snd_pcm_format_names[] = {
1934 	FORMAT(S8),
1935 	FORMAT(U8),
1936 	FORMAT(S16_LE),
1937 	FORMAT(S16_BE),
1938 	FORMAT(U16_LE),
1939 	FORMAT(U16_BE),
1940 	FORMAT(S24_LE),
1941 	FORMAT(S24_BE),
1942 	FORMAT(U24_LE),
1943 	FORMAT(U24_BE),
1944 	FORMAT(S32_LE),
1945 	FORMAT(S32_BE),
1946 	FORMAT(U32_LE),
1947 	FORMAT(U32_BE),
1948 	FORMAT(FLOAT_LE),
1949 	FORMAT(FLOAT_BE),
1950 	FORMAT(FLOAT64_LE),
1951 	FORMAT(FLOAT64_BE),
1952 	FORMAT(IEC958_SUBFRAME_LE),
1953 	FORMAT(IEC958_SUBFRAME_BE),
1954 	FORMAT(MU_LAW),
1955 	FORMAT(A_LAW),
1956 	FORMAT(IMA_ADPCM),
1957 	FORMAT(MPEG),
1958 	FORMAT(GSM),
1959 	FORMAT(S20_LE),
1960 	FORMAT(S20_BE),
1961 	FORMAT(U20_LE),
1962 	FORMAT(U20_BE),
1963 	FORMAT(SPECIAL),
1964 	FORMAT(S24_3LE),
1965 	FORMAT(S24_3BE),
1966 	FORMAT(U24_3LE),
1967 	FORMAT(U24_3BE),
1968 	FORMAT(S20_3LE),
1969 	FORMAT(S20_3BE),
1970 	FORMAT(U20_3LE),
1971 	FORMAT(U20_3BE),
1972 	FORMAT(S18_3LE),
1973 	FORMAT(S18_3BE),
1974 	FORMAT(U18_3LE),
1975 	FORMAT(U18_3BE),
1976 	FORMAT(G723_24),
1977 	FORMAT(G723_24_1B),
1978 	FORMAT(G723_40),
1979 	FORMAT(G723_40_1B),
1980 	FORMAT(DSD_U8),
1981 	FORMAT(DSD_U16_LE),
1982 	FORMAT(DSD_U32_LE),
1983 	FORMAT(DSD_U16_BE),
1984 	FORMAT(DSD_U32_BE),
1985 };
1986 
1987 static const char *const snd_pcm_format_aliases[SND_PCM_FORMAT_LAST+1] = {
1988 	FORMAT(S16),
1989 	FORMAT(U16),
1990 	FORMAT(S24),
1991 	FORMAT(U24),
1992 	FORMAT(S32),
1993 	FORMAT(U32),
1994 	FORMAT(FLOAT),
1995 	FORMAT(FLOAT64),
1996 	FORMAT(IEC958_SUBFRAME),
1997 	FORMAT(S20),
1998 	FORMAT(U20),
1999 };
2000 
2001 static const char *const snd_pcm_format_descriptions[] = {
2002 	FORMATD(S8, "Signed 8 bit"),
2003 	FORMATD(U8, "Unsigned 8 bit"),
2004 	FORMATD(S16_LE, "Signed 16 bit Little Endian"),
2005 	FORMATD(S16_BE, "Signed 16 bit Big Endian"),
2006 	FORMATD(U16_LE, "Unsigned 16 bit Little Endian"),
2007 	FORMATD(U16_BE, "Unsigned 16 bit Big Endian"),
2008 	FORMATD(S24_LE, "Signed 24 bit Little Endian"),
2009 	FORMATD(S24_BE, "Signed 24 bit Big Endian"),
2010 	FORMATD(U24_LE, "Unsigned 24 bit Little Endian"),
2011 	FORMATD(U24_BE, "Unsigned 24 bit Big Endian"),
2012 	FORMATD(S32_LE, "Signed 32 bit Little Endian"),
2013 	FORMATD(S32_BE, "Signed 32 bit Big Endian"),
2014 	FORMATD(U32_LE, "Unsigned 32 bit Little Endian"),
2015 	FORMATD(U32_BE, "Unsigned 32 bit Big Endian"),
2016 	FORMATD(FLOAT_LE, "Float 32 bit Little Endian"),
2017 	FORMATD(FLOAT_BE, "Float 32 bit Big Endian"),
2018 	FORMATD(FLOAT64_LE, "Float 64 bit Little Endian"),
2019 	FORMATD(FLOAT64_BE, "Float 64 bit Big Endian"),
2020 	FORMATD(IEC958_SUBFRAME_LE, "IEC-958 Little Endian"),
2021 	FORMATD(IEC958_SUBFRAME_BE, "IEC-958 Big Endian"),
2022 	FORMATD(MU_LAW, "Mu-Law"),
2023 	FORMATD(A_LAW, "A-Law"),
2024 	FORMATD(IMA_ADPCM, "Ima-ADPCM"),
2025 	FORMATD(MPEG, "MPEG"),
2026 	FORMATD(GSM, "GSM"),
2027 	FORMATD(S20_LE, "Signed 20 bit Little Endian in 4 bytes, LSB justified"),
2028 	FORMATD(S20_BE, "Signed 20 bit Big Endian in 4 bytes, LSB justified"),
2029 	FORMATD(U20_LE, "Unsigned 20 bit Little Endian in 4 bytes, LSB justified"),
2030 	FORMATD(U20_BE, "Unsigned 20 bit Big Endian in 4 bytes, LSB justified"),
2031 	FORMATD(SPECIAL, "Special"),
2032 	FORMATD(S24_3LE, "Signed 24 bit Little Endian in 3bytes"),
2033 	FORMATD(S24_3BE, "Signed 24 bit Big Endian in 3bytes"),
2034 	FORMATD(U24_3LE, "Unsigned 24 bit Little Endian in 3bytes"),
2035 	FORMATD(U24_3BE, "Unsigned 24 bit Big Endian in 3bytes"),
2036 	FORMATD(S20_3LE, "Signed 20 bit Little Endian in 3bytes"),
2037 	FORMATD(S20_3BE, "Signed 20 bit Big Endian in 3bytes"),
2038 	FORMATD(U20_3LE, "Unsigned 20 bit Little Endian in 3bytes"),
2039 	FORMATD(U20_3BE, "Unsigned 20 bit Big Endian in 3bytes"),
2040 	FORMATD(S18_3LE, "Signed 18 bit Little Endian in 3bytes"),
2041 	FORMATD(S18_3BE, "Signed 18 bit Big Endian in 3bytes"),
2042 	FORMATD(U18_3LE, "Unsigned 18 bit Little Endian in 3bytes"),
2043 	FORMATD(U18_3BE, "Unsigned 18 bit Big Endian in 3bytes"),
2044 	FORMATD(G723_24, "G.723 (ADPCM) 24 kbit/s, 8 samples in 3 bytes"),
2045 	FORMATD(G723_24_1B, "G.723 (ADPCM) 24 kbit/s, 1 sample in 1 byte"),
2046 	FORMATD(G723_40, "G.723 (ADPCM) 40 kbit/s, 8 samples in 3 bytes"),
2047 	FORMATD(G723_40_1B, "G.723 (ADPCM) 40 kbit/s, 1 sample in 1 byte"),
2048 	FORMATD(DSD_U8,  "Direct Stream Digital, 1-byte (x8), oldest bit in MSB"),
2049 	FORMATD(DSD_U16_LE, "Direct Stream Digital, 2-byte (x16), little endian, oldest bits in MSB"),
2050 	FORMATD(DSD_U32_LE, "Direct Stream Digital, 4-byte (x32), little endian, oldest bits in MSB"),
2051 	FORMATD(DSD_U16_BE, "Direct Stream Digital, 2-byte (x16), big endian, oldest bits in MSB"),
2052 	FORMATD(DSD_U32_BE, "Direct Stream Digital, 4-byte (x32), big endian, oldest bits in MSB"),
2053 };
2054 
2055 static const char *const snd_pcm_type_names[] = {
2056 	PCMTYPE(HW),
2057 	PCMTYPE(HOOKS),
2058 	PCMTYPE(MULTI),
2059 	PCMTYPE(FILE),
2060 	PCMTYPE(NULL),
2061 	PCMTYPE(SHM),
2062 	PCMTYPE(INET),
2063 	PCMTYPE(COPY),
2064 	PCMTYPE(LINEAR),
2065 	PCMTYPE(ALAW),
2066 	PCMTYPE(MULAW),
2067 	PCMTYPE(ADPCM),
2068 	PCMTYPE(RATE),
2069 	PCMTYPE(ROUTE),
2070 	PCMTYPE(PLUG),
2071 	PCMTYPE(SHARE),
2072 	PCMTYPE(METER),
2073 	PCMTYPE(MIX),
2074 	PCMTYPE(DROUTE),
2075 	PCMTYPE(LBSERVER),
2076 	PCMTYPE(LINEAR_FLOAT),
2077 	PCMTYPE(LADSPA),
2078 	PCMTYPE(DMIX),
2079 	PCMTYPE(JACK),
2080 	PCMTYPE(DSNOOP),
2081 	PCMTYPE(IEC958),
2082 	PCMTYPE(SOFTVOL),
2083 	PCMTYPE(IOPLUG),
2084 	PCMTYPE(EXTPLUG),
2085 	PCMTYPE(MMAP_EMUL),
2086 };
2087 
2088 static const char *const snd_pcm_subformat_names[] = {
2089 	SUBFORMAT(STD),
2090 	SUBFORMAT(MSBITS_MAX),
2091 	SUBFORMAT(MSBITS_20),
2092 	SUBFORMAT(MSBITS_24),
2093 };
2094 
2095 static const char *const snd_pcm_subformat_descriptions[] = {
2096 	SUBFORMATD(STD, "Standard"),
2097 	SUBFORMATD(MSBITS_MAX, "Maximum based on PCM format"),
2098 	SUBFORMATD(MSBITS_20, "20 most significant bits"),
2099 	SUBFORMATD(MSBITS_24, "24 most significant bits"),
2100 };
2101 
2102 static const char *const snd_pcm_start_mode_names[] = {
2103 	START(EXPLICIT),
2104 	START(DATA),
2105 };
2106 
2107 static const char *const snd_pcm_xrun_mode_names[] = {
2108 	XRUN(NONE),
2109 	XRUN(STOP),
2110 };
2111 
2112 static const char *const snd_pcm_tstamp_mode_names[] = {
2113 	TSTAMP(NONE),
2114 	TSTAMP(ENABLE),
2115 };
2116 
2117 static const char *const snd_pcm_tstamp_type_names[] = {
2118 	TSTAMP_TYPE(GETTIMEOFDAY),
2119 	TSTAMP_TYPE(MONOTONIC),
2120 	TSTAMP_TYPE(MONOTONIC_RAW),
2121 };
2122 #endif
2123 
2124 /**
2125  * \brief get name of PCM stream type
2126  * \param stream PCM stream type
2127  * \return ascii name of PCM stream type
2128  */
snd_pcm_stream_name(const snd_pcm_stream_t stream)2129 const char *snd_pcm_stream_name(const snd_pcm_stream_t stream)
2130 {
2131 	if (stream > SND_PCM_STREAM_LAST)
2132 		return NULL;
2133 	return snd_pcm_stream_names[stream];
2134 }
2135 
2136 /**
2137  * \brief get name of PCM access type
2138  * \param acc PCM access type
2139  * \return ascii name of PCM access type
2140  */
snd_pcm_access_name(const snd_pcm_access_t acc)2141 const char *snd_pcm_access_name(const snd_pcm_access_t acc)
2142 {
2143 	if (acc > SND_PCM_ACCESS_LAST)
2144 		return NULL;
2145 	return snd_pcm_access_names[acc];
2146 }
2147 
2148 /**
2149  * \brief get name of PCM sample format
2150  * \param format PCM sample format
2151  * \return ascii name of PCM sample format
2152  */
snd_pcm_format_name(const snd_pcm_format_t format)2153 const char *snd_pcm_format_name(const snd_pcm_format_t format)
2154 {
2155 	if (format > SND_PCM_FORMAT_LAST)
2156 		return NULL;
2157 	return snd_pcm_format_names[format];
2158 }
2159 
2160 /**
2161  * \brief get description of PCM sample format
2162  * \param format PCM sample format
2163  * \return ascii description of PCM sample format
2164  */
snd_pcm_format_description(const snd_pcm_format_t format)2165 const char *snd_pcm_format_description(const snd_pcm_format_t format)
2166 {
2167 	if (format > SND_PCM_FORMAT_LAST)
2168 		return NULL;
2169 	return snd_pcm_format_descriptions[format];
2170 }
2171 
2172 /**
2173  * \brief get PCM sample format from name
2174  * \param name PCM sample format name (case insensitive)
2175  * \return PCM sample format
2176  */
snd_pcm_format_value(const char* name)2177 snd_pcm_format_t snd_pcm_format_value(const char* name)
2178 {
2179 	snd_pcm_format_t format;
2180 	for (format = 0; format <= SND_PCM_FORMAT_LAST; format++) {
2181 		if (snd_pcm_format_names[format] &&
2182 		    strcasecmp(name, snd_pcm_format_names[format]) == 0) {
2183 			return format;
2184 		}
2185 		if (snd_pcm_format_aliases[format] &&
2186 		    strcasecmp(name, snd_pcm_format_aliases[format]) == 0) {
2187 			return format;
2188 		}
2189 	}
2190 	for (format = 0; format <= SND_PCM_FORMAT_LAST; format++) {
2191 		if (snd_pcm_format_descriptions[format] &&
2192 		    strcasecmp(name, snd_pcm_format_descriptions[format]) == 0) {
2193 			return format;
2194 		}
2195 	}
2196 	return SND_PCM_FORMAT_UNKNOWN;
2197 }
2198 
2199 /**
2200  * \brief get name of PCM sample subformat
2201  * \param subformat PCM sample subformat
2202  * \return ascii name of PCM sample subformat
2203  */
snd_pcm_subformat_name(const snd_pcm_subformat_t subformat)2204 const char *snd_pcm_subformat_name(const snd_pcm_subformat_t subformat)
2205 {
2206 	if (subformat > SND_PCM_SUBFORMAT_LAST)
2207 		return NULL;
2208 	return snd_pcm_subformat_names[subformat];
2209 }
2210 
2211 /**
2212  * \brief get description of PCM sample subformat
2213  * \param subformat PCM sample subformat
2214  * \return ascii description of PCM sample subformat
2215  */
snd_pcm_subformat_description(const snd_pcm_subformat_t subformat)2216 const char *snd_pcm_subformat_description(const snd_pcm_subformat_t subformat)
2217 {
2218 	if (subformat > SND_PCM_SUBFORMAT_LAST)
2219 		return NULL;
2220 	return snd_pcm_subformat_descriptions[subformat];
2221 }
2222 
2223 /**
2224  * \brief get PCM sample subformat from name
2225  * \param name PCM sample subformat name (case insensitive)
2226  * \return PCM sample subformat
2227  */
snd_pcm_subformat_value(const char* name)2228 snd_pcm_subformat_t snd_pcm_subformat_value(const char* name)
2229 {
2230 	snd_pcm_subformat_t subformat;
2231 
2232 	for (subformat = 0; subformat <= SND_PCM_SUBFORMAT_LAST; subformat++) {
2233 		if (snd_pcm_subformat_names[subformat] &&
2234 		    !strcasecmp(name, snd_pcm_subformat_names[subformat]))
2235 			return subformat;
2236 	}
2237 
2238 	for (subformat = 0; subformat <= SND_PCM_SUBFORMAT_LAST; subformat++) {
2239 		if (snd_pcm_subformat_descriptions[subformat] &&
2240 		    !strcasecmp(name, snd_pcm_subformat_descriptions[subformat]))
2241 			return subformat;
2242 	}
2243 
2244 	return SND_PCM_SUBFORMAT_UNKNOWN;
2245 }
2246 
2247 /**
2248  * \brief (DEPRECATED) get name of PCM start mode setting
2249  * \param mode PCM start mode
2250  * \return ascii name of PCM start mode setting
2251  */
snd_pcm_start_mode_name(snd_pcm_start_t mode)2252 const char *snd_pcm_start_mode_name(snd_pcm_start_t mode)
2253 {
2254 	if (mode > SND_PCM_START_LAST)
2255 		return NULL;
2256 	return snd_pcm_start_mode_names[mode];
2257 }
2258 
2259 #ifndef DOC_HIDDEN
2260 link_warning(snd_pcm_start_mode_name, "Warning: start_mode is deprecated, consider to use start_threshold");
2261 #endif
2262 
2263 /**
2264  * \brief (DEPRECATED) get name of PCM xrun mode setting
2265  * \param mode PCM xrun mode
2266  * \return ascii name of PCM xrun mode setting
2267  */
snd_pcm_xrun_mode_name(snd_pcm_xrun_t mode)2268 const char *snd_pcm_xrun_mode_name(snd_pcm_xrun_t mode)
2269 {
2270 	if (mode > SND_PCM_XRUN_LAST)
2271 		return NULL;
2272 	return snd_pcm_xrun_mode_names[mode];
2273 }
2274 
2275 #ifndef DOC_HIDDEN
2276 link_warning(snd_pcm_xrun_mode_name, "Warning: xrun_mode is deprecated, consider to use stop_threshold");
2277 #endif
2278 
2279 /**
2280  * \brief get name of PCM tstamp mode setting
2281  * \param mode PCM tstamp mode
2282  * \return ascii name of PCM tstamp mode setting
2283  */
snd_pcm_tstamp_mode_name(const snd_pcm_tstamp_t mode)2284 const char *snd_pcm_tstamp_mode_name(const snd_pcm_tstamp_t mode)
2285 {
2286 	if (mode > SND_PCM_TSTAMP_LAST)
2287 		return NULL;
2288 	return snd_pcm_tstamp_mode_names[mode];
2289 }
2290 
2291 /**
2292  * \brief get name of PCM tstamp type setting
2293  * \param type PCM tstamp type
2294  * \return ascii name of PCM tstamp type setting
2295  */
snd_pcm_tstamp_type_name(snd_pcm_tstamp_type_t type)2296 const char *snd_pcm_tstamp_type_name(snd_pcm_tstamp_type_t type)
2297 {
2298 	if (type > SND_PCM_TSTAMP_TYPE_LAST)
2299 		return NULL;
2300 	return snd_pcm_tstamp_type_names[type];
2301 }
2302 
2303 /**
2304  * \brief get name of PCM state
2305  * \param state PCM state
2306  * \return ascii name of PCM state
2307  */
snd_pcm_state_name(const snd_pcm_state_t state)2308 const char *snd_pcm_state_name(const snd_pcm_state_t state)
2309 {
2310 	if (state > SND_PCM_STATE_LAST)
2311 		return NULL;
2312 	return snd_pcm_state_names[state];
2313 }
2314 
2315 /**
2316  * \brief get name of PCM type
2317  * \param type PCM type
2318  * \return ascii name of PCM type
2319  */
2320 #ifndef DOXYGEN
snd_pcm_type_name(snd_pcm_type_t type)2321 EXPORT_SYMBOL const char *INTERNAL(snd_pcm_type_name)(snd_pcm_type_t type)
2322 #else
2323 const char *snd_pcm_type_name(snd_pcm_type_t type)
2324 #endif
2325 {
2326 	if (type > SND_PCM_TYPE_LAST)
2327 		return NULL;
2328 	return snd_pcm_type_names[type];
2329 }
2330 use_default_symbol_version(__snd_pcm_type_name, snd_pcm_type_name, ALSA_0.9.0);
2331 
2332 /**
2333  * \brief Dump current hardware setup for PCM
2334  * \param pcm PCM handle
2335  * \param out Output handle
2336  * \return 0 on success otherwise a negative error code
2337  */
snd_pcm_dump_hw_setup(snd_pcm_t *pcm, snd_output_t *out)2338 int snd_pcm_dump_hw_setup(snd_pcm_t *pcm, snd_output_t *out)
2339 {
2340 	assert(pcm);
2341 	assert(out);
2342 	if (CHECK_SANITY(! pcm->setup)) {
2343 		SNDMSG("PCM not set up");
2344 		return -EIO;
2345 	}
2346         snd_output_printf(out, "  stream       : %s\n", snd_pcm_stream_name(pcm->stream));
2347 	snd_output_printf(out, "  access       : %s\n", snd_pcm_access_name(pcm->access));
2348 	snd_output_printf(out, "  format       : %s\n", snd_pcm_format_name(pcm->format));
2349 	snd_output_printf(out, "  subformat    : %s\n", snd_pcm_subformat_name(pcm->subformat));
2350 	snd_output_printf(out, "  channels     : %u\n", pcm->channels);
2351 	snd_output_printf(out, "  rate         : %u\n", pcm->rate);
2352 	snd_output_printf(out, "  exact rate   : %g (%u/%u)\n",
2353 			  (pcm->rate_den ? ((double) pcm->rate_num / pcm->rate_den) : 0.0),
2354 			  pcm->rate_num, pcm->rate_den);
2355 	snd_output_printf(out, "  msbits       : %u\n", pcm->msbits);
2356 	snd_output_printf(out, "  buffer_size  : %lu\n", pcm->buffer_size);
2357 	snd_output_printf(out, "  period_size  : %lu\n", pcm->period_size);
2358 	snd_output_printf(out, "  period_time  : %u\n", pcm->period_time);
2359 	return 0;
2360 }
2361 
2362 /**
2363  * \brief Dump current software setup for PCM
2364  * \param pcm PCM handle
2365  * \param out Output handle
2366  * \return 0 on success otherwise a negative error code
2367  */
snd_pcm_dump_sw_setup(snd_pcm_t *pcm, snd_output_t *out)2368 int snd_pcm_dump_sw_setup(snd_pcm_t *pcm, snd_output_t *out)
2369 {
2370 	assert(pcm);
2371 	assert(out);
2372 	if (CHECK_SANITY(! pcm->setup)) {
2373 		SNDMSG("PCM not set up");
2374 		return -EIO;
2375 	}
2376 	snd_output_printf(out, "  tstamp_mode  : %s\n", snd_pcm_tstamp_mode_name(pcm->tstamp_mode));
2377 	snd_output_printf(out, "  tstamp_type  : %s\n", snd_pcm_tstamp_type_name(pcm->tstamp_type));
2378 	snd_output_printf(out, "  period_step  : %d\n", pcm->period_step);
2379 	snd_output_printf(out, "  avail_min    : %ld\n", pcm->avail_min);
2380 	snd_output_printf(out, "  period_event : %i\n", pcm->period_event);
2381 	snd_output_printf(out, "  start_threshold  : %ld\n", pcm->start_threshold);
2382 	snd_output_printf(out, "  stop_threshold   : %ld\n", pcm->stop_threshold);
2383 	snd_output_printf(out, "  silence_threshold: %ld\n", pcm->silence_threshold);
2384 	snd_output_printf(out, "  silence_size : %ld\n", pcm->silence_size);
2385 	snd_output_printf(out, "  boundary     : %ld\n", pcm->boundary);
2386 	return 0;
2387 }
2388 
2389 /**
2390  * \brief Dump current setup (hardware and software) for PCM
2391  * \param pcm PCM handle
2392  * \param out Output handle
2393  * \return 0 on success otherwise a negative error code
2394  */
snd_pcm_dump_setup(snd_pcm_t *pcm, snd_output_t *out)2395 int snd_pcm_dump_setup(snd_pcm_t *pcm, snd_output_t *out)
2396 {
2397 	snd_pcm_dump_hw_setup(pcm, out);
2398 	snd_pcm_dump_sw_setup(pcm, out);
2399 	return 0;
2400 }
2401 
2402 /**
2403  * \brief Dump status
2404  * \param status Status container
2405  * \param out Output handle
2406  * \return 0 on success otherwise a negative error code
2407  */
snd_pcm_status_dump(snd_pcm_status_t *status, snd_output_t *out)2408 int snd_pcm_status_dump(snd_pcm_status_t *status, snd_output_t *out)
2409 {
2410 	assert(status);
2411 	snd_output_printf(out, "  state       : %s\n", snd_pcm_state_name((snd_pcm_state_t) status->state));
2412 	snd_output_printf(out, "  trigger_time: %ld.%06ld\n",
2413 			  status->trigger_tstamp.tv_sec,
2414 			  status->trigger_tstamp.tv_nsec / 1000);
2415 	snd_output_printf(out, "  tstamp      : %ld.%06ld\n",
2416 		status->tstamp.tv_sec, status->tstamp.tv_nsec / 1000);
2417 	snd_output_printf(out, "  delay       : %ld\n", (long)status->delay);
2418 	snd_output_printf(out, "  avail       : %ld\n", (long)status->avail);
2419 	snd_output_printf(out, "  avail_max   : %ld\n", (long)status->avail_max);
2420 	return 0;
2421 }
2422 
2423 /**
2424  * \brief Dump PCM info
2425  * \param pcm PCM handle
2426  * \param out Output handle
2427  * \return 0 on success otherwise a negative error code
2428  */
snd_pcm_dump(snd_pcm_t *pcm, snd_output_t *out)2429 int snd_pcm_dump(snd_pcm_t *pcm, snd_output_t *out)
2430 {
2431 	int err = 0;
2432 
2433 	assert(pcm);
2434 	assert(out);
2435 	if (pcm->ops->dump)
2436 		pcm->ops->dump(pcm->op_arg, out);
2437 	else
2438 		err = -ENOSYS;
2439 	return err;
2440 }
2441 
2442 /**
2443  * \brief Convert bytes in frames for a PCM
2444  * \param pcm PCM handle
2445  * \param bytes quantity in bytes
2446  * \return quantity expressed in frames
2447  */
snd_pcm_bytes_to_frames(snd_pcm_t *pcm, ssize_t bytes)2448 snd_pcm_sframes_t snd_pcm_bytes_to_frames(snd_pcm_t *pcm, ssize_t bytes)
2449 {
2450 	assert(pcm);
2451 	if (CHECK_SANITY(! pcm->setup)) {
2452 		SNDMSG("PCM not set up");
2453 		return -EIO;
2454 	}
2455 	return bytes * 8 / pcm->frame_bits;
2456 }
2457 
2458 /**
2459  * \brief Convert frames in bytes for a PCM
2460  * \param pcm PCM handle
2461  * \param frames quantity in frames
2462  * \return quantity expressed in bytes
2463  */
snd_pcm_frames_to_bytes(snd_pcm_t *pcm, snd_pcm_sframes_t frames)2464 ssize_t snd_pcm_frames_to_bytes(snd_pcm_t *pcm, snd_pcm_sframes_t frames)
2465 {
2466 	assert(pcm);
2467 	if (CHECK_SANITY(! pcm->setup)) {
2468 		SNDMSG("PCM not set up");
2469 		return -EIO;
2470 	}
2471 	return frames * pcm->frame_bits / 8;
2472 }
2473 
2474 /**
2475  * \brief Convert bytes in samples for a PCM
2476  * \param pcm PCM handle
2477  * \param bytes quantity in bytes
2478  * \return quantity expressed in samples
2479  */
snd_pcm_bytes_to_samples(snd_pcm_t *pcm, ssize_t bytes)2480 long snd_pcm_bytes_to_samples(snd_pcm_t *pcm, ssize_t bytes)
2481 {
2482 	assert(pcm);
2483 	if (CHECK_SANITY(! pcm->setup)) {
2484 		SNDMSG("PCM not set up");
2485 		return -EIO;
2486 	}
2487 	return bytes * 8 / pcm->sample_bits;
2488 }
2489 
2490 /**
2491  * \brief Convert samples in bytes for a PCM
2492  * \param pcm PCM handle
2493  * \param samples quantity in samples
2494  * \return quantity expressed in bytes
2495  */
snd_pcm_samples_to_bytes(snd_pcm_t *pcm, long samples)2496 ssize_t snd_pcm_samples_to_bytes(snd_pcm_t *pcm, long samples)
2497 {
2498 	assert(pcm);
2499 	if (CHECK_SANITY(! pcm->setup)) {
2500 		SNDMSG("PCM not set up");
2501 		return -EIO;
2502 	}
2503 	return samples * pcm->sample_bits / 8;
2504 }
2505 
2506 /**
2507  * \brief Add an async handler for a PCM
2508  * \param handler Returned handler handle
2509  * \param pcm PCM handle
2510  * \param callback Callback function
2511  * \param private_data Callback private data
2512  * \return 0 otherwise a negative error code on failure
2513  *
2514  * The asynchronous callback is called when period boundary elapses.
2515  */
snd_async_add_pcm_handler(snd_async_handler_t **handler, snd_pcm_t *pcm, snd_async_callback_t callback, void *private_data)2516 int snd_async_add_pcm_handler(snd_async_handler_t **handler, snd_pcm_t *pcm,
2517 			      snd_async_callback_t callback, void *private_data)
2518 {
2519 	int err;
2520 	int was_empty;
2521 	snd_async_handler_t *h;
2522 	err = snd_async_add_handler(&h, _snd_pcm_async_descriptor(pcm),
2523 				    callback, private_data);
2524 	if (err < 0)
2525 		return err;
2526 	h->type = SND_ASYNC_HANDLER_PCM;
2527 	h->u.pcm = pcm;
2528 	was_empty = list_empty(&pcm->async_handlers);
2529 	list_add_tail(&h->hlist, &pcm->async_handlers);
2530 	if (was_empty) {
2531 		err = snd_pcm_async(pcm, snd_async_handler_get_signo(h), getpid());
2532 		if (err < 0) {
2533 			snd_async_del_handler(h);
2534 			return err;
2535 		}
2536 	}
2537 	*handler = h;
2538 	return 0;
2539 }
2540 
2541 /**
2542  * \brief Return PCM handle related to an async handler
2543  * \param handler Async handler handle
2544  * \return PCM handle
2545  */
snd_async_handler_get_pcm(snd_async_handler_t *handler)2546 snd_pcm_t *snd_async_handler_get_pcm(snd_async_handler_t *handler)
2547 {
2548 	if (handler->type != SND_ASYNC_HANDLER_PCM) {
2549 		SNDMSG("invalid handler type %d", handler->type);
2550 		return NULL;
2551 	}
2552 	return handler->u.pcm;
2553 }
2554 
2555 static const char *const build_in_pcms[] = {
2556 	"adpcm", "alaw", "copy", "dmix", "file", "hooks", "hw", "ladspa", "lfloat",
2557 	"linear", "meter", "mulaw", "multi", "null", "empty", "plug", "rate", "route", "share",
2558 	"shm", "dsnoop", "dshare", "asym", "iec958", "softvol", "mmap_emul",
2559 	NULL
2560 };
2561 
snd_pcm_open_conf(snd_pcm_t **pcmp, const char *name, snd_config_t *pcm_root, snd_config_t *pcm_conf, snd_pcm_stream_t stream, int mode)2562 static int snd_pcm_open_conf(snd_pcm_t **pcmp, const char *name,
2563 			     snd_config_t *pcm_root, snd_config_t *pcm_conf,
2564 			     snd_pcm_stream_t stream, int mode)
2565 {
2566 	const char *str;
2567 	char *buf = NULL, *buf1 = NULL;
2568 	int err;
2569 	snd_config_t *conf, *type_conf = NULL, *tmp;
2570 	snd_config_iterator_t i, next;
2571 	const char *id;
2572 	const char *lib = NULL, *open_name = NULL;
2573 	int (*open_func)(snd_pcm_t **, const char *,
2574 			 snd_config_t *, snd_config_t *,
2575 			 snd_pcm_stream_t, int) = NULL;
2576 #ifndef PIC
2577 	extern void *snd_pcm_open_symbols(void);
2578 #endif
2579 	if (snd_config_get_type(pcm_conf) != SND_CONFIG_TYPE_COMPOUND) {
2580 		char *val;
2581 		id = NULL;
2582 		snd_config_get_id(pcm_conf, &id);
2583 		val = NULL;
2584 		snd_config_get_ascii(pcm_conf, &val);
2585 		SNDERR("Invalid type for PCM %s%sdefinition (id: %s, value: %s)", name ? name : "", name ? " " : "", id, val);
2586 		free(val);
2587 		return -EINVAL;
2588 	}
2589 	err = snd_config_search(pcm_conf, "type", &conf);
2590 	if (err < 0) {
2591 		SNDERR("type is not defined");
2592 		return err;
2593 	}
2594 	err = snd_config_get_id(conf, &id);
2595 	if (err < 0) {
2596 		SNDERR("unable to get id");
2597 		return err;
2598 	}
2599 	err = snd_config_get_string(conf, &str);
2600 	if (err < 0) {
2601 		SNDERR("Invalid type for %s", id);
2602 		return err;
2603 	}
2604 	err = snd_config_search_definition(pcm_root, "pcm_type", str, &type_conf);
2605 	if (err >= 0) {
2606 		if (snd_config_get_type(type_conf) != SND_CONFIG_TYPE_COMPOUND) {
2607 			SNDERR("Invalid type for PCM type %s definition", str);
2608 			err = -EINVAL;
2609 			goto _err;
2610 		}
2611 		snd_config_for_each(i, next, type_conf) {
2612 			snd_config_t *n = snd_config_iterator_entry(i);
2613 			const char *id;
2614 			if (snd_config_get_id(n, &id) < 0)
2615 				continue;
2616 			if (strcmp(id, "comment") == 0)
2617 				continue;
2618 			if (strcmp(id, "lib") == 0) {
2619 				err = snd_config_get_string(n, &lib);
2620 				if (err < 0) {
2621 					SNDERR("Invalid type for %s", id);
2622 					goto _err;
2623 				}
2624 				continue;
2625 			}
2626 			if (strcmp(id, "open") == 0) {
2627 				err = snd_config_get_string(n, &open_name);
2628 				if (err < 0) {
2629 					SNDERR("Invalid type for %s", id);
2630 					goto _err;
2631 				}
2632 				continue;
2633 			}
2634 			SNDERR("Unknown field %s", id);
2635 			err = -EINVAL;
2636 			goto _err;
2637 		}
2638 	}
2639 	if (!open_name) {
2640 		buf = malloc(strlen(str) + 32);
2641 		if (buf == NULL) {
2642 			err = -ENOMEM;
2643 			goto _err;
2644 		}
2645 		open_name = buf;
2646 		sprintf(buf, "_snd_pcm_%s_open", str);
2647 	}
2648 	if (!lib) {
2649 		const char *const *build_in = build_in_pcms;
2650 		while (*build_in) {
2651 			if (!strcmp(*build_in, str))
2652 				break;
2653 			build_in++;
2654 		}
2655 		if (*build_in == NULL) {
2656 			buf1 = malloc(strlen(str) + 32);
2657 			if (buf1 == NULL) {
2658 				err = -ENOMEM;
2659 				goto _err;
2660 			}
2661 			lib = buf1;
2662 			sprintf(buf1, "libasound_module_pcm_%s.so", str);
2663 		}
2664 	}
2665 #ifndef PIC
2666 	snd_pcm_open_symbols();	/* this call is for static linking only */
2667 #endif
2668 	open_func = snd_dlobj_cache_get(lib, open_name,
2669 			SND_DLSYM_VERSION(SND_PCM_DLSYM_VERSION), 1);
2670 	if (open_func) {
2671 		err = open_func(pcmp, name, pcm_root, pcm_conf, stream, mode);
2672 		if (err >= 0) {
2673 			if ((*pcmp)->open_func) {
2674 				/* only init plugin (like empty, asym) */
2675 				snd_dlobj_cache_put(open_func);
2676 			} else {
2677 				(*pcmp)->open_func = open_func;
2678 			}
2679 			err = 0;
2680 		} else {
2681 			snd_dlobj_cache_put(open_func);
2682 		}
2683 	} else {
2684 		err = -ENXIO;
2685 	}
2686 	if (err >= 0) {
2687 		err = snd_config_search(pcm_root, "defaults.pcm.compat", &tmp);
2688 		if (err >= 0) {
2689 			long i;
2690 			if (snd_config_get_integer(tmp, &i) >= 0) {
2691 				if (i > 0)
2692 					(*pcmp)->compat = 1;
2693 			}
2694 		} else {
2695 			char *str = getenv("LIBASOUND_COMPAT");
2696 			if (str && *str)
2697 				(*pcmp)->compat = 1;
2698 		}
2699 		err = snd_config_search(pcm_root, "defaults.pcm.minperiodtime", &tmp);
2700 		if (err >= 0)
2701 			snd_config_get_integer(tmp, &(*pcmp)->minperiodtime);
2702 		err = 0;
2703 	}
2704        _err:
2705 	if (type_conf)
2706 		snd_config_delete(type_conf);
2707 	free(buf);
2708 	free(buf1);
2709 	return err;
2710 }
2711 
snd_pcm_open_noupdate(snd_pcm_t **pcmp, snd_config_t *root, const char *name, snd_pcm_stream_t stream, int mode, int hop)2712 static int snd_pcm_open_noupdate(snd_pcm_t **pcmp, snd_config_t *root,
2713 				 const char *name, snd_pcm_stream_t stream,
2714 				 int mode, int hop)
2715 {
2716 	int err;
2717 	snd_config_t *pcm_conf;
2718 	const char *str;
2719 
2720 	err = snd_config_search_definition(root, "pcm", name, &pcm_conf);
2721 	if (err < 0) {
2722 		SNDERR("Unknown PCM %s", name);
2723 		return err;
2724 	}
2725 	if (snd_config_get_string(pcm_conf, &str) >= 0)
2726 		err = snd_pcm_open_noupdate(pcmp, root, str, stream, mode,
2727 					    hop + 1);
2728 	else {
2729 		snd_config_set_hop(pcm_conf, hop);
2730 		err = snd_pcm_open_conf(pcmp, name, root, pcm_conf, stream, mode);
2731 	}
2732 	snd_config_delete(pcm_conf);
2733 	return err;
2734 }
2735 
2736 /**
2737  * \brief Opens a PCM
2738  * \param pcmp Returned PCM handle
2739  * \param name ASCII identifier of the PCM handle
2740  * \param stream Wanted stream
2741  * \param mode Open mode (see #SND_PCM_NONBLOCK, #SND_PCM_ASYNC)
2742  * \return 0 on success otherwise a negative error code
2743  */
snd_pcm_open(snd_pcm_t **pcmp, const char *name, snd_pcm_stream_t stream, int mode)2744 int snd_pcm_open(snd_pcm_t **pcmp, const char *name,
2745 		 snd_pcm_stream_t stream, int mode)
2746 {
2747 	snd_config_t *top;
2748 	int err;
2749 
2750 	assert(pcmp && name);
2751 	if (_snd_is_ucm_device(name)) {
2752 		name = uc_mgr_alibcfg_by_device(&top, name);
2753 		if (name == NULL)
2754 			return -ENODEV;
2755 	} else {
2756 		err = snd_config_update_ref(&top);
2757 		if (err < 0)
2758 			return err;
2759 	}
2760 	err = snd_pcm_open_noupdate(pcmp, top, name, stream, mode, 0);
2761 	snd_config_unref(top);
2762 	return err;
2763 }
2764 
2765 /**
2766  * \brief Opens a PCM using local configuration
2767  * \param pcmp Returned PCM handle
2768  * \param name ASCII identifier of the PCM handle
2769  * \param stream Wanted stream
2770  * \param mode Open mode (see #SND_PCM_NONBLOCK, #SND_PCM_ASYNC)
2771  * \param lconf Local configuration
2772  * \return 0 on success otherwise a negative error code
2773  */
snd_pcm_open_lconf(snd_pcm_t **pcmp, const char *name, snd_pcm_stream_t stream, int mode, snd_config_t *lconf)2774 int snd_pcm_open_lconf(snd_pcm_t **pcmp, const char *name,
2775 		       snd_pcm_stream_t stream, int mode,
2776 		       snd_config_t *lconf)
2777 {
2778 	assert(pcmp && name && lconf);
2779 	return snd_pcm_open_noupdate(pcmp, lconf, name, stream, mode, 0);
2780 }
2781 
2782 /**
2783  * \brief Opens a fallback PCM
2784  * \param pcmp Returned PCM handle
2785  * \param root Configuration root
2786  * \param name ASCII identifier of the PCM handle
2787  * \param orig_name The original ASCII name
2788  * \param stream Wanted stream
2789  * \param mode Open mode (see #SND_PCM_NONBLOCK, #SND_PCM_ASYNC)
2790  * \return 0 on success otherwise a negative error code
2791  */
snd_pcm_open_fallback(snd_pcm_t **pcmp, snd_config_t *root, const char *name, const char *orig_name, snd_pcm_stream_t stream, int mode)2792 int snd_pcm_open_fallback(snd_pcm_t **pcmp, snd_config_t *root,
2793 			  const char *name, const char *orig_name,
2794 			  snd_pcm_stream_t stream, int mode)
2795 {
2796 	int err;
2797 	assert(pcmp && name && root);
2798 	err = snd_pcm_open_noupdate(pcmp, root, name, stream, mode, 0);
2799 	if (err >= 0) {
2800 		free((*pcmp)->name);
2801 		(*pcmp)->name = orig_name ? strdup(orig_name) : NULL;
2802 	}
2803 	return err;
2804 }
2805 
2806 #ifndef DOC_HIDDEN
snd_pcm_new(snd_pcm_t **pcmp, snd_pcm_type_t type, const char *name, snd_pcm_stream_t stream, int mode)2807 int snd_pcm_new(snd_pcm_t **pcmp, snd_pcm_type_t type, const char *name,
2808 		snd_pcm_stream_t stream, int mode)
2809 {
2810 	snd_pcm_t *pcm;
2811 #ifdef THREAD_SAFE_API
2812 	pthread_mutexattr_t attr;
2813 #endif
2814 
2815 	pcm = calloc(1, sizeof(*pcm));
2816 	if (!pcm)
2817 		return -ENOMEM;
2818 	pcm->type = type;
2819 	if (name)
2820 		pcm->name = strdup(name);
2821 	pcm->stream = stream;
2822 	pcm->mode = mode;
2823 	pcm->poll_fd_count = 1;
2824 	pcm->poll_fd = -1;
2825 	pcm->op_arg = pcm;
2826 	pcm->fast_op_arg = pcm;
2827 	INIT_LIST_HEAD(&pcm->async_handlers);
2828 #ifdef THREAD_SAFE_API
2829 	pthread_mutexattr_init(&attr);
2830 #ifdef HAVE_PTHREAD_MUTEX_RECURSIVE
2831 	pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
2832 #endif
2833 	pthread_mutex_init(&pcm->lock, &attr);
2834 	pthread_mutexattr_destroy(&attr);
2835 	/* use locking as default;
2836 	 * each plugin may suppress this in its open call
2837 	 */
2838 	pcm->need_lock = 1;
2839 	if (mode & SND_PCM_ASYNC) {
2840 		/* async handler may lead to a deadlock; suppose no MT */
2841 		pcm->lock_enabled = 0;
2842 	} else {
2843 		/* set lock_enabled field depending on $LIBASOUND_THREAD_SAFE */
2844 		static int do_lock_enable = -1; /* uninitialized */
2845 
2846 		/* evaluate env var only once at the first open for consistency */
2847 		if (do_lock_enable == -1) {
2848 			char *p = getenv("LIBASOUND_THREAD_SAFE");
2849 			do_lock_enable = !p || *p != '0';
2850 		}
2851 		pcm->lock_enabled = do_lock_enable;
2852 	}
2853 #endif
2854 	*pcmp = pcm;
2855 	return 0;
2856 }
2857 
snd_pcm_free(snd_pcm_t *pcm)2858 int snd_pcm_free(snd_pcm_t *pcm)
2859 {
2860 	assert(pcm);
2861 	free(pcm->name);
2862 	free(pcm->hw.link_dst);
2863 	free(pcm->appl.link_dst);
2864 	snd_dlobj_cache_put(pcm->open_func);
2865 #ifdef THREAD_SAFE_API
2866 	pthread_mutex_destroy(&pcm->lock);
2867 #endif
2868 	free(pcm);
2869 	return 0;
2870 }
2871 
snd_pcm_open_named_slave(snd_pcm_t **pcmp, const char *name, snd_config_t *root, snd_config_t *conf, snd_pcm_stream_t stream, int mode, snd_config_t *parent_conf)2872 int snd_pcm_open_named_slave(snd_pcm_t **pcmp, const char *name,
2873 			     snd_config_t *root,
2874 			     snd_config_t *conf, snd_pcm_stream_t stream,
2875 			     int mode, snd_config_t *parent_conf)
2876 {
2877 	const char *str;
2878 	int hop;
2879 
2880 	if ((hop = snd_config_check_hop(parent_conf)) < 0)
2881 		return hop;
2882 	if (snd_config_get_string(conf, &str) >= 0)
2883 		return snd_pcm_open_noupdate(pcmp, root, str, stream, mode,
2884 					     hop + 1);
2885 	return snd_pcm_open_conf(pcmp, name, root, conf, stream, mode);
2886 }
2887 #endif
2888 
2889 /**
2890  * \brief Wait for a PCM to become ready
2891  * \param pcm PCM handle
2892  * \param timeout maximum time in milliseconds to wait,
2893  *        a -1 value means infinity (SND_PCM_WAIT_INFINITE),
2894  *	       see also SND_PCM_WAIT_IO and SND_PCM_WAIT_DRAIN
2895  * \return a positive value on success otherwise a negative error code
2896  *         (-EPIPE for the xrun and -ESTRPIPE for the suspended status,
2897  *          others for general errors)
2898  * \retval 0 timeout occurred
2899  * \retval 1 PCM stream is ready for I/O
2900  *
2901  * The function is thread-safe when built with the proper option.
2902  */
snd_pcm_wait(snd_pcm_t *pcm, int timeout)2903 int snd_pcm_wait(snd_pcm_t *pcm, int timeout)
2904 {
2905 	int err;
2906 
2907 	__snd_pcm_lock(pcm->fast_op_arg); /* forced lock */
2908 	err = __snd_pcm_wait_in_lock(pcm, timeout);
2909 	__snd_pcm_unlock(pcm->fast_op_arg);
2910 	return err;
2911 }
2912 
2913 #ifndef DOC_HIDDEN
2914 /* locked version */
__snd_pcm_wait_in_lock(snd_pcm_t *pcm, int timeout)2915 int __snd_pcm_wait_in_lock(snd_pcm_t *pcm, int timeout)
2916 {
2917 	int err;
2918 
2919 	/* NOTE: avail_min check can be skipped during draining */
2920 	if (__snd_pcm_state(pcm) != SND_PCM_STATE_DRAINING &&
2921 	    !snd_pcm_may_wait_for_avail_min(pcm, snd_pcm_mmap_avail(pcm))) {
2922 		/* check more precisely */
2923 		err = pcm_state_to_error(__snd_pcm_state(pcm));
2924 		return err < 0 ? err : 1;
2925 	}
2926 	return snd_pcm_wait_nocheck(pcm, timeout);
2927 }
2928 
__snd_pcm_wait_io_timeout(snd_pcm_t *pcm)2929 static int __snd_pcm_wait_io_timeout(snd_pcm_t *pcm)
2930 {
2931 	int timeout;
2932 
2933 	/* period size is the time boundary */
2934 	timeout = (pcm->period_size * 1000ULL) / pcm->rate;
2935 	/* should not happen */
2936 	if (timeout < 0)
2937 		timeout = 0;
2938 	/* add extra time of 200 milliseconds */
2939 	timeout += 200;
2940 	return timeout;
2941 }
2942 
__snd_pcm_wait_drain_timeout(snd_pcm_t *pcm)2943 static int __snd_pcm_wait_drain_timeout(snd_pcm_t *pcm)
2944 {
2945 	int timeout;
2946 
2947 	/* for capture, there's no reason to wait, just one iteration */
2948 	if (snd_pcm_stream(pcm) == SND_PCM_STREAM_CAPTURE)
2949 		return 0;
2950 	/* result is in milliseconds */
2951 	timeout = (snd_pcm_mmap_playback_delay(pcm) * 1000LL) / pcm->rate;
2952 	/* should not happen */
2953 	if (timeout < 0)
2954 		timeout = 0;
2955 	/* add extra time of 200 milliseconds */
2956 	timeout += 200;
2957 	return timeout;
2958 }
2959 
2960 /*
2961  * like snd_pcm_wait() but doesn't check mmap_avail before calling poll()
2962  *
2963  * used in drain code in some plugins
2964  *
2965  * This function is called inside pcm lock.
2966  */
snd_pcm_wait_nocheck(snd_pcm_t *pcm, int timeout)2967 int snd_pcm_wait_nocheck(snd_pcm_t *pcm, int timeout)
2968 {
2969 	struct pollfd *pfd;
2970 	unsigned short revents = 0;
2971 	int npfds, err, err_poll;
2972 
2973 	npfds = __snd_pcm_poll_descriptors_count(pcm);
2974 	if (npfds <= 0 || npfds >= 16) {
2975 		SNDERR("Invalid poll_fds %d", npfds);
2976 		return -EIO;
2977 	}
2978 	pfd = alloca(sizeof(*pfd) * npfds);
2979 	err = __snd_pcm_poll_descriptors(pcm, pfd, npfds);
2980 	if (err < 0)
2981 		return err;
2982 	if (err != npfds) {
2983 		SNDMSG("invalid poll descriptors %d", err);
2984 		return -EIO;
2985 	}
2986 	if (timeout == SND_PCM_WAIT_IO)
2987 		timeout = __snd_pcm_wait_io_timeout(pcm);
2988 	else if (timeout == SND_PCM_WAIT_DRAIN)
2989 		timeout = __snd_pcm_wait_drain_timeout(pcm);
2990 	else if (timeout < -1)
2991 		SNDMSG("invalid snd_pcm_wait timeout argument %d", timeout);
2992 	do {
2993 		__snd_pcm_unlock(pcm->fast_op_arg);
2994 		err_poll = poll(pfd, npfds, timeout);
2995 		__snd_pcm_lock(pcm->fast_op_arg);
2996 		if (err_poll < 0) {
2997 			if (errno == EINTR && !PCMINABORT(pcm) && !(pcm->mode & SND_PCM_EINTR))
2998 		                continue;
2999 			return -errno;
3000                 }
3001 		if (! err_poll)
3002 			break;
3003 		err = __snd_pcm_poll_revents(pcm, pfd, npfds, &revents);
3004 		if (err < 0)
3005 			return err;
3006 		if (revents & (POLLERR | POLLNVAL)) {
3007 			/* check more precisely */
3008 			err = pcm_state_to_error(__snd_pcm_state(pcm));
3009 			return err < 0 ? err : -EIO;
3010 		}
3011 	} while (!(revents & (POLLIN | POLLOUT)));
3012 #if 0 /* very useful code to test poll related problems */
3013 	{
3014 		snd_pcm_sframes_t avail_update;
3015 		__snd_pcm_hwsync(pcm);
3016 		avail_update = __snd_pcm_avail_update(pcm);
3017 		if (avail_update < (snd_pcm_sframes_t)pcm->avail_min) {
3018 			printf("*** snd_pcm_wait() FATAL ERROR!!!\n");
3019 			printf("avail_min = %li, avail_update = %li\n", pcm->avail_min, avail_update);
3020 		}
3021 	}
3022 #endif
3023 	return err_poll > 0 ? 1 : 0;
3024 }
3025 #endif
3026 
3027 /**
3028  * \brief Return number of frames ready to be read (capture) / written (playback)
3029  * \param pcm PCM handle
3030  * \return a positive number of frames ready otherwise a negative
3031  * error code
3032  *
3033  * On capture does all the actions needed to transport to application
3034  * level all the ready frames across underlying layers.
3035  *
3036  * The position is not synced with hardware (driver) position in the sound
3037  * ring buffer in this function. This function is a light version of
3038  * #snd_pcm_avail() .
3039  *
3040  * Using this function is ideal after poll() or select() when audio
3041  * file descriptor made the event and when application expects just period
3042  * timing.
3043  *
3044  * Also this function might be called after #snd_pcm_delay() or
3045  * #snd_pcm_hwsync() functions to move private ring buffer pointers
3046  * in alsa-lib (the internal plugin chain).
3047  *
3048  * The function is thread-safe when built with the proper option.
3049  */
snd_pcm_avail_update(snd_pcm_t *pcm)3050 snd_pcm_sframes_t snd_pcm_avail_update(snd_pcm_t *pcm)
3051 {
3052 	snd_pcm_sframes_t result;
3053 
3054 	snd_pcm_lock(pcm->fast_op_arg);
3055 	result = __snd_pcm_avail_update(pcm);
3056 	snd_pcm_unlock(pcm->fast_op_arg);
3057 	return result;
3058 }
3059 
3060 /**
3061  * \brief Return number of frames ready to be read (capture) / written (playback)
3062  * \param pcm PCM handle
3063  * \return a positive number of frames ready otherwise a negative
3064  * error code
3065  *
3066  * On capture does all the actions needed to transport to application
3067  * level all the ready frames across underlying layers.
3068  *
3069  * The position is synced with hardware (driver) position in the sound
3070  * ring buffer in this functions.
3071  *
3072  * The function is thread-safe when built with the proper option.
3073  */
snd_pcm_avail(snd_pcm_t *pcm)3074 snd_pcm_sframes_t snd_pcm_avail(snd_pcm_t *pcm)
3075 {
3076 	int err;
3077 	snd_pcm_sframes_t result;
3078 
3079 	assert(pcm);
3080 	if (CHECK_SANITY(! pcm->setup)) {
3081 		SNDMSG("PCM not set up");
3082 		return -EIO;
3083 	}
3084 	snd_pcm_lock(pcm->fast_op_arg);
3085 	err = __snd_pcm_hwsync(pcm);
3086 	if (err < 0)
3087 		result = err;
3088 	else
3089 		result = __snd_pcm_avail_update(pcm);
3090 	snd_pcm_unlock(pcm->fast_op_arg);
3091 	return result;
3092 }
3093 
3094 /**
3095  * \brief Combine snd_pcm_avail and snd_pcm_delay functions
3096  * \param pcm PCM handle
3097  * \param availp Number of available frames in the ring buffer
3098  * \param delayp Total I/O latency in frames
3099  * \return zero on success otherwise a negative error code
3100  *
3101  * The avail and delay values retuned are in sync.
3102  *
3103  * The function is thread-safe when built with the proper option.
3104  */
snd_pcm_avail_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *availp, snd_pcm_sframes_t *delayp)3105 int snd_pcm_avail_delay(snd_pcm_t *pcm,
3106 			snd_pcm_sframes_t *availp,
3107 			snd_pcm_sframes_t *delayp)
3108 {
3109 	snd_pcm_sframes_t sf;
3110 	int err;
3111 
3112 	assert(pcm && availp && delayp);
3113 	if (CHECK_SANITY(! pcm->setup)) {
3114 		SNDMSG("PCM not set up");
3115 		return -EIO;
3116 	}
3117 	snd_pcm_lock(pcm->fast_op_arg);
3118 	err = __snd_pcm_hwsync(pcm);
3119 	if (err < 0)
3120 		goto unlock;
3121 	sf = __snd_pcm_avail_update(pcm);
3122 	if (sf < 0) {
3123 		err = (int)sf;
3124 		goto unlock;
3125 	}
3126 	err = __snd_pcm_delay(pcm, delayp);
3127 	if (err < 0)
3128 		goto unlock;
3129 	*availp = sf;
3130 	err = 0;
3131  unlock:
3132 	snd_pcm_unlock(pcm->fast_op_arg);
3133 	return err;
3134 }
3135 
3136 /**
3137  * \brief Silence an area
3138  * \param dst_area area specification
3139  * \param dst_offset offset in frames inside area
3140  * \param samples samples to silence
3141  * \param format PCM sample format
3142  * \return 0 on success otherwise a negative error code
3143  */
snd_pcm_area_silence(const snd_pcm_channel_area_t *dst_area, snd_pcm_uframes_t dst_offset, unsigned int samples, snd_pcm_format_t format)3144 int snd_pcm_area_silence(const snd_pcm_channel_area_t *dst_area, snd_pcm_uframes_t dst_offset,
3145 			 unsigned int samples, snd_pcm_format_t format)
3146 {
3147 	/* FIXME: sub byte resolution and odd dst_offset */
3148 	char *dst;
3149 	unsigned int dst_step;
3150 	int width;
3151 	uint64_t silence;
3152 	if (!dst_area->addr)
3153 		return 0;
3154 	dst = snd_pcm_channel_area_addr(dst_area, dst_offset);
3155 	width = snd_pcm_format_physical_width(format);
3156 	silence = snd_pcm_format_silence_64(format);
3157         /*
3158          * Iterate copying silent sample for sample data aligned to 64 bit.
3159          * This is a fast path.
3160          */
3161         if (dst_area->step == (unsigned int) width &&
3162             width != 24 &&
3163             ((intptr_t)dst & 7) == 0) {
3164 		unsigned int dwords = samples * width / 64;
3165 		uint64_t *dstp = (uint64_t *)dst;
3166 		samples -= dwords * 64 / width;
3167 		while (dwords-- > 0)
3168 			*dstp++ = silence;
3169 		if (samples == 0)
3170 			return 0;
3171 		dst = (char *)dstp;
3172 	}
3173 	dst_step = dst_area->step / 8;
3174 	switch (width) {
3175 	case 4: {
3176 		uint8_t s0 = silence & 0xf0;
3177 		uint8_t s1 = silence & 0x0f;
3178 		int dstbit = dst_area->first % 8;
3179 		int dstbit_step = dst_area->step % 8;
3180 		while (samples-- > 0) {
3181 			if (dstbit) {
3182 				*dst &= 0xf0;
3183 				*dst |= s1;
3184 			} else {
3185 				*dst &= 0x0f;
3186 				*dst |= s0;
3187 			}
3188 			dst += dst_step;
3189 			dstbit += dstbit_step;
3190 			if (dstbit == 8) {
3191 				dst++;
3192 				dstbit = 0;
3193 			}
3194 		}
3195 		break;
3196 	}
3197 	case 8: {
3198 		uint8_t sil = silence;
3199 		while (samples-- > 0) {
3200 			*dst = sil;
3201 			dst += dst_step;
3202 		}
3203 		break;
3204 	}
3205 	case 16: {
3206 		uint16_t sil = silence;
3207 		while (samples-- > 0) {
3208 			*(uint16_t*)dst = sil;
3209 			dst += dst_step;
3210 		}
3211 		break;
3212 	}
3213 	case 24: {
3214 		while (samples-- > 0) {
3215 #ifdef SNDRV_LITTLE_ENDIAN
3216 			*(dst + 0) = silence >> 0;
3217 			*(dst + 1) = silence >> 8;
3218 			*(dst + 2) = silence >> 16;
3219 #else
3220 			*(dst + 2) = silence >> 0;
3221 			*(dst + 1) = silence >> 8;
3222 			*(dst + 0) = silence >> 16;
3223 #endif
3224 			dst += dst_step;
3225 		}
3226 	}
3227 		break;
3228 	case 32: {
3229 		uint32_t sil = silence;
3230 		while (samples-- > 0) {
3231 			*(uint32_t*)dst = sil;
3232 			dst += dst_step;
3233 		}
3234 		break;
3235 	}
3236 	case 64: {
3237 		while (samples-- > 0) {
3238 			*(uint64_t*)dst = silence;
3239 			dst += dst_step;
3240 		}
3241 		break;
3242 	}
3243 	default:
3244 		SNDMSG("invalid format width %d", width);
3245 		return -EINVAL;
3246 	}
3247 	return 0;
3248 }
3249 
3250 /**
3251  * \brief Silence one or more areas
3252  * \param dst_areas areas specification (one for each channel)
3253  * \param dst_offset offset in frames inside area
3254  * \param channels channels count
3255  * \param frames frames to silence
3256  * \param format PCM sample format
3257  * \return 0 on success otherwise a negative error code
3258  */
snd_pcm_areas_silence(const snd_pcm_channel_area_t *dst_areas, snd_pcm_uframes_t dst_offset, unsigned int channels, snd_pcm_uframes_t frames, snd_pcm_format_t format)3259 int snd_pcm_areas_silence(const snd_pcm_channel_area_t *dst_areas, snd_pcm_uframes_t dst_offset,
3260 			  unsigned int channels, snd_pcm_uframes_t frames, snd_pcm_format_t format)
3261 {
3262 	int width = snd_pcm_format_physical_width(format);
3263 	while (channels > 0) {
3264 		void *addr = dst_areas->addr;
3265 		unsigned int step = dst_areas->step;
3266 		const snd_pcm_channel_area_t *begin = dst_areas;
3267 		int channels1 = channels;
3268 		unsigned int chns = 0;
3269 		int err;
3270 		while (1) {
3271 			channels1--;
3272 			chns++;
3273 			dst_areas++;
3274 			if (channels1 == 0 ||
3275 			    dst_areas->addr != addr ||
3276 			    dst_areas->step != step ||
3277 			    dst_areas->first != dst_areas[-1].first + width)
3278 				break;
3279 		}
3280 		if (chns > 1 && chns * width == step) {
3281 			/* Collapse the areas */
3282 			snd_pcm_channel_area_t d;
3283 			d.addr = begin->addr;
3284 			d.first = begin->first;
3285 			d.step = width;
3286 			err = snd_pcm_area_silence(&d, dst_offset * chns, frames * chns, format);
3287 			channels -= chns;
3288 		} else {
3289 			err = snd_pcm_area_silence(begin, dst_offset, frames, format);
3290 			dst_areas = begin + 1;
3291 			channels--;
3292 		}
3293 		if (err < 0)
3294 			return err;
3295 	}
3296 	return 0;
3297 }
3298 
3299 
3300 /**
3301  * \brief Copy an area
3302  * \param dst_area destination area specification
3303  * \param dst_offset offset in frames inside destination area
3304  * \param src_area source area specification
3305  * \param src_offset offset in frames inside source area
3306  * \param samples samples to copy
3307  * \param format PCM sample format
3308  * \return 0 on success otherwise a negative error code
3309  */
snd_pcm_area_copy(const snd_pcm_channel_area_t *dst_area, snd_pcm_uframes_t dst_offset, const snd_pcm_channel_area_t *src_area, snd_pcm_uframes_t src_offset, unsigned int samples, snd_pcm_format_t format)3310 int snd_pcm_area_copy(const snd_pcm_channel_area_t *dst_area, snd_pcm_uframes_t dst_offset,
3311 		      const snd_pcm_channel_area_t *src_area, snd_pcm_uframes_t src_offset,
3312 		      unsigned int samples, snd_pcm_format_t format)
3313 {
3314 	/* FIXME: sub byte resolution and odd dst_offset */
3315 	const char *src;
3316 	char *dst;
3317 	int width;
3318 	int src_step, dst_step;
3319 	if (dst_area == src_area && dst_offset == src_offset)
3320 		return 0;
3321 	if (!src_area->addr)
3322 		return snd_pcm_area_silence(dst_area, dst_offset, samples, format);
3323 	src = snd_pcm_channel_area_addr(src_area, src_offset);
3324 	if (!dst_area->addr)
3325 		return 0;
3326 	dst = snd_pcm_channel_area_addr(dst_area, dst_offset);
3327 	width = snd_pcm_format_physical_width(format);
3328 	if (src_area->step == (unsigned int) width &&
3329 	    dst_area->step == (unsigned int) width) {
3330 		size_t bytes = samples * width / 8;
3331 		samples -= bytes * 8 / width;
3332 		assert(src < dst || src >= dst + bytes);
3333 		assert(dst < src || dst >= src + bytes);
3334 		memcpy(dst, src, bytes);
3335 		if (samples == 0)
3336 			return 0;
3337 	}
3338 	src_step = src_area->step / 8;
3339 	dst_step = dst_area->step / 8;
3340 	switch (width) {
3341 	case 4: {
3342 		int srcbit = src_area->first % 8;
3343 		int srcbit_step = src_area->step % 8;
3344 		int dstbit = dst_area->first % 8;
3345 		int dstbit_step = dst_area->step % 8;
3346 		while (samples-- > 0) {
3347 			unsigned char srcval;
3348 			if (srcbit)
3349 				srcval = *src & 0x0f;
3350 			else
3351 				srcval = *src & 0xf0;
3352 			if (dstbit)
3353 				*dst &= 0xf0;
3354 			else
3355 				*dst &= 0x0f;
3356 			*dst |= srcval;
3357 			src += src_step;
3358 			srcbit += srcbit_step;
3359 			if (srcbit == 8) {
3360 				src++;
3361 				srcbit = 0;
3362 			}
3363 			dst += dst_step;
3364 			dstbit += dstbit_step;
3365 			if (dstbit == 8) {
3366 				dst++;
3367 				dstbit = 0;
3368 			}
3369 		}
3370 		break;
3371 	}
3372 	case 8: {
3373 		while (samples-- > 0) {
3374 			*dst = *src;
3375 			src += src_step;
3376 			dst += dst_step;
3377 		}
3378 		break;
3379 	}
3380 	case 16: {
3381 		while (samples-- > 0) {
3382 			*(uint16_t*)dst = *(const uint16_t*)src;
3383 			src += src_step;
3384 			dst += dst_step;
3385 		}
3386 		break;
3387 	}
3388 	case 24:
3389 		while (samples-- > 0) {
3390 			*(dst + 0) = *(src + 0);
3391 			*(dst + 1) = *(src + 1);
3392 			*(dst + 2) = *(src + 2);
3393 			src += src_step;
3394 			dst += dst_step;
3395 		}
3396 		break;
3397 	case 32: {
3398 		while (samples-- > 0) {
3399 			*(uint32_t*)dst = *(const uint32_t*)src;
3400 			src += src_step;
3401 			dst += dst_step;
3402 		}
3403 		break;
3404 	}
3405 	case 64: {
3406 		while (samples-- > 0) {
3407 			*(uint64_t*)dst = *(const uint64_t*)src;
3408 			src += src_step;
3409 			dst += dst_step;
3410 		}
3411 		break;
3412 	}
3413 	default:
3414 		SNDMSG("invalid format width %d", width);
3415 		return -EINVAL;
3416 	}
3417 	return 0;
3418 }
3419 
3420 /**
3421  * \brief Copy one or more areas
3422  * \param dst_areas destination areas specification (one for each channel)
3423  * \param dst_offset offset in frames inside destination area
3424  * \param src_areas source areas specification (one for each channel)
3425  * \param src_offset offset in frames inside source area
3426  * \param channels channels count
3427  * \param frames frames to copy
3428  * \param format PCM sample format
3429  * \return 0 on success otherwise a negative error code
3430  */
snd_pcm_areas_copy(const snd_pcm_channel_area_t *dst_areas, snd_pcm_uframes_t dst_offset, const snd_pcm_channel_area_t *src_areas, snd_pcm_uframes_t src_offset, unsigned int channels, snd_pcm_uframes_t frames, snd_pcm_format_t format)3431 int snd_pcm_areas_copy(const snd_pcm_channel_area_t *dst_areas, snd_pcm_uframes_t dst_offset,
3432 		       const snd_pcm_channel_area_t *src_areas, snd_pcm_uframes_t src_offset,
3433 		       unsigned int channels, snd_pcm_uframes_t frames, snd_pcm_format_t format)
3434 {
3435 	int width = snd_pcm_format_physical_width(format);
3436 	assert(dst_areas);
3437 	assert(src_areas);
3438 	if (! channels) {
3439 		SNDMSG("invalid channels %d", channels);
3440 		return -EINVAL;
3441 	}
3442 	if (! frames) {
3443 		SNDMSG("invalid frames %ld", frames);
3444 		return -EINVAL;
3445 	}
3446 	while (channels > 0) {
3447 		unsigned int step = src_areas->step;
3448 		void *src_addr = src_areas->addr;
3449 		const snd_pcm_channel_area_t *src_start = src_areas;
3450 		void *dst_addr = dst_areas->addr;
3451 		const snd_pcm_channel_area_t *dst_start = dst_areas;
3452 		int channels1 = channels;
3453 		unsigned int chns = 0;
3454 		while (dst_areas->step == step) {
3455 			channels1--;
3456 			chns++;
3457 			src_areas++;
3458 			dst_areas++;
3459 			if (channels1 == 0 ||
3460 			    src_areas->step != step ||
3461 			    src_areas->addr != src_addr ||
3462 			    dst_areas->addr != dst_addr ||
3463 			    src_areas->first != src_areas[-1].first + width ||
3464 			    dst_areas->first != dst_areas[-1].first + width)
3465 				break;
3466 		}
3467 		if (chns > 1 && chns * width == step) {
3468 			if (src_offset != dst_offset ||
3469 			    src_start->addr != dst_start->addr ||
3470 			    src_start->first != dst_start->first) {
3471 				/* Collapse the areas */
3472 				snd_pcm_channel_area_t s, d;
3473 				s.addr = src_start->addr;
3474 				s.first = src_start->first;
3475 				s.step = width;
3476 				d.addr = dst_start->addr;
3477 				d.first = dst_start->first;
3478 				d.step = width;
3479 				snd_pcm_area_copy(&d, dst_offset * chns,
3480 						  &s, src_offset * chns,
3481 						  frames * chns, format);
3482 			}
3483 			channels -= chns;
3484 		} else {
3485 			snd_pcm_area_copy(dst_start, dst_offset,
3486 					  src_start, src_offset,
3487 					  frames, format);
3488 			src_areas = src_start + 1;
3489 			dst_areas = dst_start + 1;
3490 			channels--;
3491 		}
3492 	}
3493 	return 0;
3494 }
3495 
3496 /**
3497  * \brief Copy one or more areas
3498  * \param dst_channels destination areas specification (one for each channel)
3499  * \param dst_offset offset in frames inside destination area
3500  * \param dst_size size in frames of the destination buffer
3501  * \param src_channels source areas specification (one for each channel)
3502  * \param src_offset offset in frames inside source area
3503  * \param src_size size in frames of the source buffer
3504  * \param channels channels count
3505  * \param frames frames to copy
3506  * \param format PCM sample format
3507  * \return 0 on success otherwise a negative error code
3508  */
snd_pcm_areas_copy_wrap(const snd_pcm_channel_area_t *dst_channels, snd_pcm_uframes_t dst_offset, const snd_pcm_uframes_t dst_size, const snd_pcm_channel_area_t *src_channels, snd_pcm_uframes_t src_offset, const snd_pcm_uframes_t src_size, const unsigned int channels, snd_pcm_uframes_t frames, const snd_pcm_format_t format)3509 int snd_pcm_areas_copy_wrap(const snd_pcm_channel_area_t *dst_channels,
3510 			    snd_pcm_uframes_t dst_offset,
3511 			    const snd_pcm_uframes_t dst_size,
3512 			    const snd_pcm_channel_area_t *src_channels,
3513 			    snd_pcm_uframes_t src_offset,
3514 			    const snd_pcm_uframes_t src_size,
3515 			    const unsigned int channels,
3516 			    snd_pcm_uframes_t frames,
3517 			    const snd_pcm_format_t format)
3518 {
3519 	while (frames > 0) {
3520 		int err;
3521 		snd_pcm_uframes_t xfer = frames;
3522 		/* do not write above the destination buffer */
3523 		if ((dst_offset + xfer) > dst_size)
3524 			xfer = dst_size - dst_offset;
3525 		/* do not read from above the source buffer */
3526 		if ((src_offset + xfer) > src_size)
3527 			xfer = src_size - src_offset;
3528 		err = snd_pcm_areas_copy(dst_channels, dst_offset, src_channels,
3529 					 src_offset, channels, xfer, format);
3530 		if (err < 0)
3531 			return err;
3532 
3533 		dst_offset += xfer;
3534 		if (dst_offset >= dst_size)
3535 			dst_offset = 0;
3536 		src_offset += xfer;
3537 		if (src_offset >= src_size)
3538 			src_offset = 0;
3539 		frames -= xfer;
3540 	}
3541 
3542 	return 0;
3543 }
3544 
dump_one_param(snd_pcm_hw_params_t *params, unsigned int k, snd_output_t *out)3545 static void dump_one_param(snd_pcm_hw_params_t *params, unsigned int k, snd_output_t *out)
3546 {
3547 	snd_output_printf(out, "%s: ", snd_pcm_hw_param_name(k));
3548 	snd_pcm_hw_param_dump(params, k, out);
3549 	snd_output_putc(out, '\n');
3550 }
3551 
3552 /**
3553  * \brief Dump a PCM hardware configuration space
3554  * \param params Configuration space
3555  * \param out Output handle
3556  * \return 0 on success otherwise a negative error code
3557  */
snd_pcm_hw_params_dump(snd_pcm_hw_params_t *params, snd_output_t *out)3558 int snd_pcm_hw_params_dump(snd_pcm_hw_params_t *params, snd_output_t *out)
3559 {
3560 	unsigned int k;
3561 	for (k = SND_PCM_HW_PARAM_FIRST_MASK; k <= SND_PCM_HW_PARAM_LAST_MASK; k++)
3562 		dump_one_param(params, k, out);
3563 	for (k = SND_PCM_HW_PARAM_FIRST_INTERVAL; k <= SND_PCM_HW_PARAM_LAST_INTERVAL; k++)
3564 		dump_one_param(params, k, out);
3565 	return 0;
3566 }
3567 
3568 /**
3569  * \brief Check if hardware supports sample-resolution mmap for given configuration
3570  * \param params Configuration space
3571  * \retval 0 Hardware doesn't support sample-resolution mmap
3572  * \retval 1 Hardware supports sample-resolution mmap
3573  *
3574  * This function should only be called when the configuration space
3575  * contains a single configuration. Call #snd_pcm_hw_params to choose
3576  * a single configuration from the configuration space.
3577  */
snd_pcm_hw_params_can_mmap_sample_resolution(const snd_pcm_hw_params_t *params)3578 int snd_pcm_hw_params_can_mmap_sample_resolution(const snd_pcm_hw_params_t *params)
3579 {
3580 	assert(params);
3581 	if (CHECK_SANITY(params->info == ~0U)) {
3582 		SNDMSG("invalid PCM info field");
3583 		return 0; /* FIXME: should be a negative error? */
3584 	}
3585 	return !!(params->info & SNDRV_PCM_INFO_MMAP_VALID);
3586 }
3587 
3588 /**
3589  * \brief Check if hardware does double buffering for start/stop for given configuration
3590  * \param params Configuration space
3591  * \retval 0 Hardware doesn't do double buffering for start/stop
3592  * \retval 1 Hardware does double buffering for start/stop
3593  *
3594  * This function should only be called when the configuration space
3595  * contains a single configuration. Call #snd_pcm_hw_params to choose
3596  * a single configuration from the configuration space.
3597  */
snd_pcm_hw_params_is_double(const snd_pcm_hw_params_t *params)3598 int snd_pcm_hw_params_is_double(const snd_pcm_hw_params_t *params)
3599 {
3600 	assert(params);
3601 	if (CHECK_SANITY(params->info == ~0U)) {
3602 		SNDMSG("invalid PCM info field");
3603 		return 0; /* FIXME: should be a negative error? */
3604 	}
3605 	return !!(params->info & SNDRV_PCM_INFO_DOUBLE);
3606 }
3607 
3608 /**
3609  * \brief Check if hardware does double buffering for data transfers for given configuration
3610  * \param params Configuration space
3611  * \retval 0 Hardware doesn't do double buffering for data transfers
3612  * \retval 1 Hardware does double buffering for data transfers
3613  *
3614  * This function should only be called when the configuration space
3615  * contains a single configuration. Call #snd_pcm_hw_params to choose
3616  * a single configuration from the configuration space.
3617  */
snd_pcm_hw_params_is_batch(const snd_pcm_hw_params_t *params)3618 int snd_pcm_hw_params_is_batch(const snd_pcm_hw_params_t *params)
3619 {
3620 	assert(params);
3621 	if (CHECK_SANITY(params->info == ~0U)) {
3622 		SNDMSG("invalid PCM info field");
3623 		return 0; /* FIXME: should be a negative error? */
3624 	}
3625 	return !!(params->info & SNDRV_PCM_INFO_BATCH);
3626 }
3627 
3628 /**
3629  * \brief Check if hardware does block transfers for samples for given configuration
3630  * \param params Configuration space
3631  * \retval 0 Hardware doesn't block transfers
3632  * \retval 1 Hardware does block transfers
3633  *
3634  * This function should only be called when the configuration space
3635  * contains a single configuration. Call #snd_pcm_hw_params to choose
3636  * a single configuration from the configuration space.
3637  */
snd_pcm_hw_params_is_block_transfer(const snd_pcm_hw_params_t *params)3638 int snd_pcm_hw_params_is_block_transfer(const snd_pcm_hw_params_t *params)
3639 {
3640 	assert(params);
3641 	if (CHECK_SANITY(params->info == ~0U)) {
3642 		SNDMSG("invalid PCM info field");
3643 		return 0; /* FIXME: should be a negative error? */
3644 	}
3645 	return !!(params->info & SNDRV_PCM_INFO_BLOCK_TRANSFER);
3646 }
3647 
3648 /**
3649  * \brief Check if timestamps are monotonic for given configuration
3650  * \param params Configuration space
3651  * \retval 0 Device doesn't do monotomic timestamps
3652  * \retval 1 Device does monotonic timestamps
3653  *
3654  * This function should only be called when the configuration space
3655  * contains a single configuration. Call #snd_pcm_hw_params to choose
3656  * a single configuration from the configuration space.
3657  */
snd_pcm_hw_params_is_monotonic(const snd_pcm_hw_params_t *params)3658 int snd_pcm_hw_params_is_monotonic(const snd_pcm_hw_params_t *params)
3659 {
3660 	assert(params);
3661 	if (CHECK_SANITY(params->info == ~0U)) {
3662 		SNDMSG("invalid PCM info field");
3663 		return 0; /* FIXME: should be a negative error? */
3664 	}
3665 	return !!(params->info & SND_PCM_INFO_MONOTONIC);
3666 }
3667 
3668 /**
3669  * \brief Check if hardware supports overrange detection
3670  * \param params Configuration space
3671  * \retval 0 Hardware doesn't support overrange detection
3672  * \retval 1 Hardware supports overrange detection
3673  *
3674  * This function should only be called when the configuration space
3675  * contains a single configuration. Call #snd_pcm_hw_params to choose
3676  * a single configuration from the configuration space.
3677  */
snd_pcm_hw_params_can_overrange(const snd_pcm_hw_params_t *params)3678 int snd_pcm_hw_params_can_overrange(const snd_pcm_hw_params_t *params)
3679 {
3680 	assert(params);
3681 	if (CHECK_SANITY(params->info == ~0U)) {
3682 		SNDMSG("invalid PCM info field");
3683 		return 0; /* FIXME: should be a negative error? */
3684 	}
3685 	return !!(params->info & SNDRV_PCM_INFO_OVERRANGE);
3686 }
3687 
3688 /**
3689  * \brief Check if hardware supports pause
3690  * \param params Configuration space
3691  * \retval 0 Hardware doesn't support pause
3692  * \retval 1 Hardware supports pause
3693  *
3694  * This function should only be called when the configuration space
3695  * contains a single configuration. Call #snd_pcm_hw_params to choose
3696  * a single configuration from the configuration space.
3697  */
snd_pcm_hw_params_can_pause(const snd_pcm_hw_params_t *params)3698 int snd_pcm_hw_params_can_pause(const snd_pcm_hw_params_t *params)
3699 {
3700 	assert(params);
3701 	if (CHECK_SANITY(params->info == ~0U)) {
3702 		SNDMSG("invalid PCM info field");
3703 		return 0; /* FIXME: should be a negative error? */
3704 	}
3705 	return !!(params->info & SNDRV_PCM_INFO_PAUSE);
3706 }
3707 
3708 /**
3709  * \brief Check if hardware supports resume
3710  * \param params Configuration space
3711  * \retval 0 Hardware doesn't support resume
3712  * \retval 1 Hardware supports resume
3713  *
3714  * This function should only be called when the configuration space
3715  * contains a single configuration. Call #snd_pcm_hw_params to choose
3716  * a single configuration from the configuration space.
3717  */
snd_pcm_hw_params_can_resume(const snd_pcm_hw_params_t *params)3718 int snd_pcm_hw_params_can_resume(const snd_pcm_hw_params_t *params)
3719 {
3720 	assert(params);
3721 	if (CHECK_SANITY(params->info == ~0U)) {
3722 		SNDMSG("invalid PCM info field");
3723 		return 0; /* FIXME: should be a negative error? */
3724 	}
3725 	return !!(params->info & SNDRV_PCM_INFO_RESUME);
3726 }
3727 
3728 /**
3729  * \brief Check if hardware does half-duplex only
3730  * \param params Configuration space
3731  * \retval 0 Hardware doesn't do half-duplex
3732  * \retval 1 Hardware does half-duplex
3733  *
3734  * This function should only be called when the configuration space
3735  * contains a single configuration. Call #snd_pcm_hw_params to choose
3736  * a single configuration from the configuration space.
3737  */
snd_pcm_hw_params_is_half_duplex(const snd_pcm_hw_params_t *params)3738 int snd_pcm_hw_params_is_half_duplex(const snd_pcm_hw_params_t *params)
3739 {
3740 	assert(params);
3741 	if (CHECK_SANITY(params->info == ~0U)) {
3742 		SNDMSG("invalid PCM info field");
3743 		return 0; /* FIXME: should be a negative error? */
3744 	}
3745 	return !!(params->info & SNDRV_PCM_INFO_HALF_DUPLEX);
3746 }
3747 
3748 /**
3749  * \brief Check if hardware does joint-duplex (playback and capture are somewhat correlated)
3750  * \param params Configuration space
3751  * \retval 0 Hardware doesn't do joint-duplex
3752  * \retval 1 Hardware does joint-duplex
3753  *
3754  * This function should only be called when the configuration space
3755  * contains a single configuration. Call #snd_pcm_hw_params to choose
3756  * a single configuration from the configuration space.
3757  */
snd_pcm_hw_params_is_joint_duplex(const snd_pcm_hw_params_t *params)3758 int snd_pcm_hw_params_is_joint_duplex(const snd_pcm_hw_params_t *params)
3759 {
3760 	assert(params);
3761 	if (CHECK_SANITY(params->info == ~0U)) {
3762 		SNDMSG("invalid PCM info field");
3763 		return 0; /* FIXME: should be a negative error? */
3764 	}
3765 	return !!(params->info & SNDRV_PCM_INFO_JOINT_DUPLEX);
3766 }
3767 
3768 /**
3769  * \brief Check if hardware supports synchronized start with sample resolution
3770  * \param params Configuration space
3771  * \retval 0 Hardware doesn't support synchronized start
3772  * \retval 1 Hardware supports synchronized start
3773  *
3774  * This function should only be called when the configuration space
3775  * contains a single configuration. Call #snd_pcm_hw_params to choose
3776  * a single configuration from the configuration space.
3777  */
snd_pcm_hw_params_can_sync_start(const snd_pcm_hw_params_t *params)3778 int snd_pcm_hw_params_can_sync_start(const snd_pcm_hw_params_t *params)
3779 {
3780 	assert(params);
3781 	if (CHECK_SANITY(params->info == ~0U)) {
3782 		SNDMSG("invalid PCM info field");
3783 		return 0; /* FIXME: should be a negative error? */
3784 	}
3785 	return !!(params->info & SNDRV_PCM_INFO_SYNC_START);
3786 }
3787 
3788 /**
3789  * \brief Check if hardware can disable period wakeups
3790  * \param params Configuration space
3791  * \retval 0 Hardware cannot disable period wakeups
3792  * \retval 1 Hardware can disable period wakeups
3793  */
snd_pcm_hw_params_can_disable_period_wakeup(const snd_pcm_hw_params_t *params)3794 int snd_pcm_hw_params_can_disable_period_wakeup(const snd_pcm_hw_params_t *params)
3795 {
3796 	assert(params);
3797 	if (CHECK_SANITY(params->info == ~0U)) {
3798 		SNDMSG("invalid PCM info field");
3799 		return 0; /* FIXME: should be a negative error? */
3800 	}
3801 	return !!(params->info & SNDRV_PCM_INFO_NO_PERIOD_WAKEUP);
3802 }
3803 
3804 /**
3805  * \brief Check if hardware is capable of perfect drain
3806  * \param params Configuration space
3807  * \retval 0 Hardware doesn't do perfect drain
3808  * \retval 1 Hardware does perfect drain
3809  *
3810  * This function should only be called when the configuration space
3811  * contains a single configuration. Call #snd_pcm_hw_params to choose
3812  * a single configuration from the configuration space.
3813  *
3814  * Perfect drain means that the hardware does not use samples
3815  * beyond the stream application pointer.
3816  */
snd_pcm_hw_params_is_perfect_drain(const snd_pcm_hw_params_t *params)3817 int snd_pcm_hw_params_is_perfect_drain(const snd_pcm_hw_params_t *params)
3818 {
3819 	assert(params);
3820 	if (CHECK_SANITY(params->info == ~0U)) {
3821 		SNDMSG("invalid PCM info field");
3822 		return 0; /* FIXME: should be a negative error? */
3823 	}
3824 	return !!(params->info & SNDRV_PCM_INFO_PERFECT_DRAIN);
3825 }
3826 
3827 /**
3828  * \brief Check if hardware supports audio wallclock timestamps
3829  * \param params Configuration space
3830  * \retval 0 Hardware doesn't support audio wallclock timestamps
3831  * \retval 1 Hardware supports audio wallclock timestamps
3832  *
3833  * This function should only be called when the configuration space
3834  * contains a single configuration. Call #snd_pcm_hw_params to choose
3835  * a single configuration from the configuration space.
3836  */
snd_pcm_hw_params_supports_audio_wallclock_ts(const snd_pcm_hw_params_t *params)3837 int snd_pcm_hw_params_supports_audio_wallclock_ts(const snd_pcm_hw_params_t *params)
3838 {
3839 	/* deprecated */
3840 	return snd_pcm_hw_params_supports_audio_ts_type(params,
3841 							SNDRV_PCM_AUDIO_TSTAMP_TYPE_COMPAT);
3842 }
3843 
3844 /**
3845  * \brief Check if hardware supports type of audio timestamps
3846  * \param params Configuration space
3847  * \param type   Audio timestamp type
3848  * \retval 0 Hardware doesn't support type of audio timestamps
3849  * \retval 1 Hardware supports type of audio timestamps
3850  *
3851  * This function should only be called when the configuration space
3852  * contains a single configuration. Call #snd_pcm_hw_params to choose
3853  * a single configuration from the configuration space.
3854  */
snd_pcm_hw_params_supports_audio_ts_type(const snd_pcm_hw_params_t *params, int type)3855 int snd_pcm_hw_params_supports_audio_ts_type(const snd_pcm_hw_params_t *params, int type)
3856 {
3857 	assert(params);
3858 	if (CHECK_SANITY(params->info == ~0U)) {
3859 		SNDMSG("invalid PCM info field");
3860 		return 0; /* FIXME: should be a negative error? */
3861 	}
3862 	switch (type) {
3863 	case SNDRV_PCM_AUDIO_TSTAMP_TYPE_COMPAT:
3864 		return !!(params->info & SNDRV_PCM_INFO_HAS_WALL_CLOCK); /* deprecated */
3865 	case SNDRV_PCM_AUDIO_TSTAMP_TYPE_DEFAULT:
3866 		return 1; /* always supported, based on hw_ptr */
3867 	case SNDRV_PCM_AUDIO_TSTAMP_TYPE_LINK:
3868 		return !!(params->info & SNDRV_PCM_INFO_HAS_LINK_ATIME);
3869 	case SNDRV_PCM_AUDIO_TSTAMP_TYPE_LINK_ABSOLUTE:
3870 		return !!(params->info & SNDRV_PCM_INFO_HAS_LINK_ABSOLUTE_ATIME);
3871 	case SNDRV_PCM_AUDIO_TSTAMP_TYPE_LINK_ESTIMATED:
3872 		return !!(params->info & SNDRV_PCM_INFO_HAS_LINK_ESTIMATED_ATIME);
3873 	case SNDRV_PCM_AUDIO_TSTAMP_TYPE_LINK_SYNCHRONIZED:
3874 		return !!(params->info & SNDRV_PCM_INFO_HAS_LINK_SYNCHRONIZED_ATIME);
3875 	default:
3876 		return 0;
3877 	}
3878 }
3879 
3880 /**
3881  * \brief Get rate exact info from a configuration space
3882  * \param params Configuration space
3883  * \param rate_num Pointer to returned rate numerator
3884  * \param rate_den Pointer to returned rate denominator
3885  * \return 0 otherwise a negative error code if the info is not available
3886  *
3887  * This function should only be called when the configuration space
3888  * contains a single configuration. Call #snd_pcm_hw_params to choose
3889  * a single configuration from the configuration space.
3890  */
snd_pcm_hw_params_get_rate_numden(const snd_pcm_hw_params_t *params, unsigned int *rate_num, unsigned int *rate_den)3891 int snd_pcm_hw_params_get_rate_numden(const snd_pcm_hw_params_t *params,
3892 				      unsigned int *rate_num, unsigned int *rate_den)
3893 {
3894 	assert(params);
3895 	if (CHECK_SANITY(params->rate_den == 0)) {
3896 		SNDMSG("invalid rate_den value");
3897 		return -EINVAL;
3898 	}
3899 	*rate_num = params->rate_num;
3900 	*rate_den = params->rate_den;
3901 	return 0;
3902 }
3903 
3904 /**
3905  * \brief Get sample resolution info from a configuration space
3906  * \param params Configuration space
3907  * \return sample resolution (in bits) otherwise a negative error code if the info is not available
3908  *
3909  * For linear formats, this function returns sample resolution -
3910  * used bits starting from the first usable significant bit defined by
3911  * the format (e.g. bit 31 for S32_LE format or bit 23 for S24_LE format -
3912  * starting from bit zero). Application may use full sample bit range defined
3913  * by the format, but additional bits (outside this sample resolution) are
3914  * stripped (not processed).
3915  *
3916  * For non-linear formats, this value may have a special meaning which may be defined in future.
3917  *
3918  * This function should only be called when the configuration space
3919  * contains a single configuration. Call #snd_pcm_hw_params to choose
3920  * a single configuration from the configuration space.
3921  */
snd_pcm_hw_params_get_sbits(const snd_pcm_hw_params_t *params)3922 int snd_pcm_hw_params_get_sbits(const snd_pcm_hw_params_t *params)
3923 {
3924 	assert(params);
3925 	if (CHECK_SANITY(params->msbits == 0)) {
3926 		SNDMSG("invalid msbits value");
3927 		return -EINVAL;
3928 	}
3929 	return params->msbits;
3930 }
3931 
3932 /**
3933  * \brief Get hardware FIFO size info from a configuration space
3934  * \param params Configuration space
3935  * \return FIFO size in frames otherwise a negative error code if the info is not available
3936  *
3937  * This function should only be called when the configuration space
3938  * contains a single configuration. Call #snd_pcm_hw_params to choose
3939  * a single configuration from the configuration space.
3940  */
snd_pcm_hw_params_get_fifo_size(const snd_pcm_hw_params_t *params)3941 int snd_pcm_hw_params_get_fifo_size(const snd_pcm_hw_params_t *params)
3942 {
3943 	assert(params);
3944 	if (CHECK_SANITY(params->info == ~0U)) {
3945 		SNDMSG("invalid PCM info field");
3946 		return -EINVAL;
3947 	}
3948 	return params->fifo_size;
3949 }
3950 
3951 /**
3952  * \brief Fill params with a full configuration space for a PCM
3953  * \param pcm PCM handle
3954  * \param params Configuration space
3955  *
3956  * The configuration space will be filled with all possible ranges
3957  * for the PCM device.
3958  *
3959  * Note that the configuration space may be constrained by the
3960  * currently installed configuration on the PCM device. To remove
3961  * any constrains, free the configuration with #snd_pcm_hw_free
3962  * first.
3963  */
snd_pcm_hw_params_any(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)3964 int snd_pcm_hw_params_any(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
3965 {
3966 	_snd_pcm_hw_params_any(params);
3967 	return snd_pcm_hw_refine(pcm, params);
3968 }
3969 
3970 /**
3971  * \brief get size of #snd_pcm_access_mask_t
3972  * \return size in bytes
3973  */
snd_pcm_access_mask_sizeofnull3974 size_t snd_pcm_access_mask_sizeof()
3975 {
3976 	return sizeof(snd_pcm_access_mask_t);
3977 }
3978 
3979 /**
3980  * \brief allocate an empty #snd_pcm_access_mask_t using standard malloc
3981  * \param ptr returned pointer
3982  * \return 0 on success otherwise negative error code
3983  */
snd_pcm_access_mask_malloc(snd_pcm_access_mask_t **ptr)3984 int snd_pcm_access_mask_malloc(snd_pcm_access_mask_t **ptr)
3985 {
3986 	assert(ptr);
3987 	*ptr = calloc(1, sizeof(snd_pcm_access_mask_t));
3988 	if (!*ptr)
3989 		return -ENOMEM;
3990 	return 0;
3991 }
3992 
3993 /**
3994  * \brief frees a previously allocated #snd_pcm_access_mask_t
3995  * \param obj pointer to object to free
3996  */
snd_pcm_access_mask_free(snd_pcm_access_mask_t *obj)3997 void snd_pcm_access_mask_free(snd_pcm_access_mask_t *obj)
3998 {
3999 	free(obj);
4000 }
4001 
4002 /**
4003  * \brief copy one #snd_pcm_access_mask_t to another
4004  * \param dst pointer to destination
4005  * \param src pointer to source
4006  */
snd_pcm_access_mask_copy(snd_pcm_access_mask_t *dst, const snd_pcm_access_mask_t *src)4007 void snd_pcm_access_mask_copy(snd_pcm_access_mask_t *dst, const snd_pcm_access_mask_t *src)
4008 {
4009 	assert(dst && src);
4010 	*dst = *src;
4011 }
4012 
4013 /**
4014  * \brief reset all bits in a #snd_pcm_access_mask_t
4015  * \param mask pointer to mask
4016  */
snd_pcm_access_mask_none(snd_pcm_access_mask_t *mask)4017 void snd_pcm_access_mask_none(snd_pcm_access_mask_t *mask)
4018 {
4019 	snd_mask_none((snd_mask_t *) mask);
4020 }
4021 
4022 /**
4023  * \brief set all bits in a #snd_pcm_access_mask_t
4024  * \param mask pointer to mask
4025  */
snd_pcm_access_mask_any(snd_pcm_access_mask_t *mask)4026 void snd_pcm_access_mask_any(snd_pcm_access_mask_t *mask)
4027 {
4028 	snd_mask_any((snd_mask_t *) mask);
4029 }
4030 
4031 /**
4032  * \brief test the presence of an access type in a #snd_pcm_access_mask_t
4033  * \param mask pointer to mask
4034  * \param val access type
4035  */
snd_pcm_access_mask_test(const snd_pcm_access_mask_t *mask, snd_pcm_access_t val)4036 int snd_pcm_access_mask_test(const snd_pcm_access_mask_t *mask, snd_pcm_access_t val)
4037 {
4038 	return snd_mask_test((const snd_mask_t *) mask, (unsigned long) val);
4039 }
4040 
4041 /**
4042  * \brief test, if given a #snd_pcm_access_mask_t is empty
4043  * \param mask pointer to mask
4044  * \retval 0 not empty
4045  * \retval 1 empty
4046  */
snd_pcm_access_mask_empty(const snd_pcm_access_mask_t *mask)4047 int snd_pcm_access_mask_empty(const snd_pcm_access_mask_t *mask)
4048 {
4049 	return snd_mask_empty((const snd_mask_t *) mask);
4050 }
4051 
4052 /**
4053  * \brief make an access type present in a #snd_pcm_access_mask_t
4054  * \param mask pointer to mask
4055  * \param val access type
4056  */
snd_pcm_access_mask_set(snd_pcm_access_mask_t *mask, snd_pcm_access_t val)4057 void snd_pcm_access_mask_set(snd_pcm_access_mask_t *mask, snd_pcm_access_t val)
4058 {
4059 	snd_mask_set((snd_mask_t *) mask, (unsigned long) val);
4060 }
4061 
4062 /**
4063  * \brief make an access type missing from a #snd_pcm_access_mask_t
4064  * \param mask pointer to mask
4065  * \param val access type
4066  */
snd_pcm_access_mask_reset(snd_pcm_access_mask_t *mask, snd_pcm_access_t val)4067 void snd_pcm_access_mask_reset(snd_pcm_access_mask_t *mask, snd_pcm_access_t val)
4068 {
4069 	snd_mask_reset((snd_mask_t *) mask, (unsigned long) val);
4070 }
4071 
4072 /**
4073  * \brief get size of #snd_pcm_format_mask_t
4074  * \return size in bytes
4075  */
snd_pcm_format_mask_sizeofnull4076 size_t snd_pcm_format_mask_sizeof()
4077 {
4078 	return sizeof(snd_pcm_format_mask_t);
4079 }
4080 
4081 /**
4082  * \brief allocate an empty #snd_pcm_format_mask_t using standard malloc
4083  * \param ptr returned pointer
4084  * \return 0 on success otherwise negative error code
4085  */
snd_pcm_format_mask_malloc(snd_pcm_format_mask_t **ptr)4086 int snd_pcm_format_mask_malloc(snd_pcm_format_mask_t **ptr)
4087 {
4088 	assert(ptr);
4089 	*ptr = calloc(1, sizeof(snd_pcm_format_mask_t));
4090 	if (!*ptr)
4091 		return -ENOMEM;
4092 	return 0;
4093 }
4094 
4095 /**
4096  * \brief frees a previously allocated #snd_pcm_format_mask_t
4097  * \param obj pointer to object to free
4098  */
snd_pcm_format_mask_free(snd_pcm_format_mask_t *obj)4099 void snd_pcm_format_mask_free(snd_pcm_format_mask_t *obj)
4100 {
4101 	free(obj);
4102 }
4103 
4104 /**
4105  * \brief copy one #snd_pcm_format_mask_t to another
4106  * \param dst pointer to destination
4107  * \param src pointer to source
4108  */
snd_pcm_format_mask_copy(snd_pcm_format_mask_t *dst, const snd_pcm_format_mask_t *src)4109 void snd_pcm_format_mask_copy(snd_pcm_format_mask_t *dst, const snd_pcm_format_mask_t *src)
4110 {
4111 	assert(dst && src);
4112 	*dst = *src;
4113 }
4114 
4115 /**
4116  * \brief reset all bits in a #snd_pcm_format_mask_t
4117  * \param mask pointer to mask
4118  */
snd_pcm_format_mask_none(snd_pcm_format_mask_t *mask)4119 void snd_pcm_format_mask_none(snd_pcm_format_mask_t *mask)
4120 {
4121 	snd_mask_none((snd_mask_t *) mask);
4122 }
4123 
4124 /**
4125  * \brief set all bits in a #snd_pcm_format_mask_t
4126  * \param mask pointer to mask
4127  */
snd_pcm_format_mask_any(snd_pcm_format_mask_t *mask)4128 void snd_pcm_format_mask_any(snd_pcm_format_mask_t *mask)
4129 {
4130 	snd_mask_any((snd_mask_t *) mask);
4131 }
4132 
4133 /**
4134  * \brief test the presence of a format in a #snd_pcm_format_mask_t
4135  * \param mask pointer to mask
4136  * \param val format
4137  */
snd_pcm_format_mask_test(const snd_pcm_format_mask_t *mask, snd_pcm_format_t val)4138 int snd_pcm_format_mask_test(const snd_pcm_format_mask_t *mask, snd_pcm_format_t val)
4139 {
4140 	return snd_mask_test((const snd_mask_t *) mask, (unsigned long) val);
4141 }
4142 
4143 /**
4144  * \brief test, if given a #snd_pcm_format_mask_t is empty
4145  * \param mask pointer to mask
4146  * \retval 0 not empty
4147  * \retval 1 empty
4148  */
snd_pcm_format_mask_empty(const snd_pcm_format_mask_t *mask)4149 int snd_pcm_format_mask_empty(const snd_pcm_format_mask_t *mask)
4150 {
4151 	return snd_mask_empty((const snd_mask_t *) mask);
4152 }
4153 
4154 /**
4155  * \brief make a format present in a #snd_pcm_format_mask_t
4156  * \param mask pointer to mask
4157  * \param val format
4158  */
snd_pcm_format_mask_set(snd_pcm_format_mask_t *mask, snd_pcm_format_t val)4159 void snd_pcm_format_mask_set(snd_pcm_format_mask_t *mask, snd_pcm_format_t val)
4160 {
4161 	snd_mask_set((snd_mask_t *) mask, (unsigned long) val);
4162 }
4163 
4164 /**
4165  * \brief make a format missing from a #snd_pcm_format_mask_t
4166  * \param mask pointer to mask
4167  * \param val format
4168  */
snd_pcm_format_mask_reset(snd_pcm_format_mask_t *mask, snd_pcm_format_t val)4169 void snd_pcm_format_mask_reset(snd_pcm_format_mask_t *mask, snd_pcm_format_t val)
4170 {
4171 	snd_mask_reset((snd_mask_t *) mask, (unsigned long) val);
4172 }
4173 
4174 
4175 /**
4176  * \brief get size of #snd_pcm_subformat_mask_t
4177  * \return size in bytes
4178  */
snd_pcm_subformat_mask_sizeofnull4179 size_t snd_pcm_subformat_mask_sizeof()
4180 {
4181 	return sizeof(snd_pcm_subformat_mask_t);
4182 }
4183 
4184 /**
4185  * \brief allocate an empty #snd_pcm_subformat_mask_t using standard malloc
4186  * \param ptr returned pointer
4187  * \return 0 on success otherwise negative error code
4188  */
snd_pcm_subformat_mask_malloc(snd_pcm_subformat_mask_t **ptr)4189 int snd_pcm_subformat_mask_malloc(snd_pcm_subformat_mask_t **ptr)
4190 {
4191 	assert(ptr);
4192 	*ptr = calloc(1, sizeof(snd_pcm_subformat_mask_t));
4193 	if (!*ptr)
4194 		return -ENOMEM;
4195 	return 0;
4196 }
4197 
4198 /**
4199  * \brief frees a previously allocated #snd_pcm_subformat_mask_t
4200  * \param obj pointer to object to free
4201  */
snd_pcm_subformat_mask_free(snd_pcm_subformat_mask_t *obj)4202 void snd_pcm_subformat_mask_free(snd_pcm_subformat_mask_t *obj)
4203 {
4204 	free(obj);
4205 }
4206 
4207 /**
4208  * \brief copy one #snd_pcm_subformat_mask_t to another
4209  * \param dst pointer to destination
4210  * \param src pointer to source
4211  */
snd_pcm_subformat_mask_copy(snd_pcm_subformat_mask_t *dst, const snd_pcm_subformat_mask_t *src)4212 void snd_pcm_subformat_mask_copy(snd_pcm_subformat_mask_t *dst, const snd_pcm_subformat_mask_t *src)
4213 {
4214 	assert(dst && src);
4215 	*dst = *src;
4216 }
4217 
4218 /**
4219  * \brief reset all bits in a #snd_pcm_subformat_mask_t
4220  * \param mask pointer to mask
4221  */
snd_pcm_subformat_mask_none(snd_pcm_subformat_mask_t *mask)4222 void snd_pcm_subformat_mask_none(snd_pcm_subformat_mask_t *mask)
4223 {
4224 	snd_mask_none((snd_mask_t *) mask);
4225 }
4226 
4227 /**
4228  * \brief set all bits in a #snd_pcm_subformat_mask_t
4229  * \param mask pointer to mask
4230  */
snd_pcm_subformat_mask_any(snd_pcm_subformat_mask_t *mask)4231 void snd_pcm_subformat_mask_any(snd_pcm_subformat_mask_t *mask)
4232 {
4233 	snd_mask_any((snd_mask_t *) mask);
4234 }
4235 
4236 /**
4237  * \brief test the presence of a subformat in a #snd_pcm_subformat_mask_t
4238  * \param mask pointer to mask
4239  * \param val subformat
4240  */
snd_pcm_subformat_mask_test(const snd_pcm_subformat_mask_t *mask, snd_pcm_subformat_t val)4241 int snd_pcm_subformat_mask_test(const snd_pcm_subformat_mask_t *mask, snd_pcm_subformat_t val)
4242 {
4243 	return snd_mask_test((const snd_mask_t *) mask, (unsigned long) val);
4244 }
4245 
4246 /**
4247  * \brief test, if given a #snd_pcm_subformat_mask_t is empty
4248  * \param mask pointer to mask
4249  * \retval 0 not empty
4250  * \retval 1 empty
4251  */
snd_pcm_subformat_mask_empty(const snd_pcm_subformat_mask_t *mask)4252 int snd_pcm_subformat_mask_empty(const snd_pcm_subformat_mask_t *mask)
4253 {
4254 	return snd_mask_empty((const snd_mask_t *) mask);
4255 }
4256 
4257 /**
4258  * \brief make a subformat present in a #snd_pcm_subformat_mask_t
4259  * \param mask pointer to mask
4260  * \param val subformat
4261  */
snd_pcm_subformat_mask_set(snd_pcm_subformat_mask_t *mask, snd_pcm_subformat_t val)4262 void snd_pcm_subformat_mask_set(snd_pcm_subformat_mask_t *mask, snd_pcm_subformat_t val)
4263 {
4264 	snd_mask_set((snd_mask_t *) mask, (unsigned long) val);
4265 }
4266 
4267 /**
4268  * \brief make a subformat missing from a #snd_pcm_subformat_mask_t
4269  * \param mask pointer to mask
4270  * \param val subformat
4271  */
snd_pcm_subformat_mask_reset(snd_pcm_subformat_mask_t *mask, snd_pcm_subformat_t val)4272 void snd_pcm_subformat_mask_reset(snd_pcm_subformat_mask_t *mask, snd_pcm_subformat_t val)
4273 {
4274 	snd_mask_reset((snd_mask_t *) mask, (unsigned long) val);
4275 }
4276 
4277 
4278 /**
4279  * \brief get size of #snd_pcm_hw_params_t
4280  * \return size in bytes
4281  */
snd_pcm_hw_params_sizeofnull4282 size_t snd_pcm_hw_params_sizeof()
4283 {
4284 	return sizeof(snd_pcm_hw_params_t);
4285 }
4286 
4287 /**
4288  * \brief allocate an invalid #snd_pcm_hw_params_t using standard malloc
4289  * \param ptr returned pointer
4290  * \return 0 on success otherwise negative error code
4291  */
snd_pcm_hw_params_malloc(snd_pcm_hw_params_t **ptr)4292 int snd_pcm_hw_params_malloc(snd_pcm_hw_params_t **ptr)
4293 {
4294 	assert(ptr);
4295 	*ptr = calloc(1, sizeof(snd_pcm_hw_params_t));
4296 	if (!*ptr)
4297 		return -ENOMEM;
4298 	return 0;
4299 }
4300 
4301 /**
4302  * \brief frees a previously allocated #snd_pcm_hw_params_t
4303  * \param obj pointer to object to free
4304  */
snd_pcm_hw_params_free(snd_pcm_hw_params_t *obj)4305 void snd_pcm_hw_params_free(snd_pcm_hw_params_t *obj)
4306 {
4307 	free(obj);
4308 }
4309 
4310 /**
4311  * \brief copy one #snd_pcm_hw_params_t to another
4312  * \param dst pointer to destination
4313  * \param src pointer to source
4314  */
snd_pcm_hw_params_copy(snd_pcm_hw_params_t *dst, const snd_pcm_hw_params_t *src)4315 void snd_pcm_hw_params_copy(snd_pcm_hw_params_t *dst, const snd_pcm_hw_params_t *src)
4316 {
4317 	assert(dst && src);
4318 	*dst = *src;
4319 }
4320 
4321 
4322 /**
4323  * \brief Extract access type from a configuration space
4324  * \param params Configuration space
4325  * \param access Returned value
4326  * \return access type otherwise a negative error code if the configuration space does not contain a single value
4327  */
4328 #ifndef DOXYGEN
snd_pcm_hw_params_get_access(const snd_pcm_hw_params_t *params, snd_pcm_access_t *access)4329 EXPORT_SYMBOL int INTERNAL(snd_pcm_hw_params_get_access)(const snd_pcm_hw_params_t *params, snd_pcm_access_t *access)
4330 #else
4331 int snd_pcm_hw_params_get_access(const snd_pcm_hw_params_t *params, snd_pcm_access_t *access)
4332 #endif
4333 {
4334 	unsigned int _val;
4335 	int err = snd_pcm_hw_param_get(params, SND_PCM_HW_PARAM_ACCESS, &_val, NULL);
4336 	if (err >= 0)
4337 		*access = _val;
4338 	return err;
4339 }
4340 
4341 /**
4342  * \brief Verify if an access type is available inside a configuration space for a PCM
4343  * \param pcm PCM handle
4344  * \param params Configuration space
4345  * \param access access type
4346  * \return 0 if available a negative error code otherwise
4347  */
snd_pcm_hw_params_test_access(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_t access)4348 int snd_pcm_hw_params_test_access(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_t access)
4349 {
4350 	return snd_pcm_hw_param_set(pcm, params, SND_TEST, SND_PCM_HW_PARAM_ACCESS, access, 0);
4351 }
4352 
4353 /**
4354  * \brief Restrict a configuration space to contain only one access type
4355  * \param pcm PCM handle
4356  * \param params Configuration space
4357  * \param access access type
4358  * \return 0 otherwise a negative error code if configuration space would become empty
4359  */
snd_pcm_hw_params_set_access(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_t access)4360 int snd_pcm_hw_params_set_access(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_t access)
4361 {
4362 	return snd_pcm_hw_param_set(pcm, params, SND_TRY, SND_PCM_HW_PARAM_ACCESS, access, 0);
4363 }
4364 
4365 /**
4366  * \brief Restrict a configuration space to contain only its first access type
4367  * \param pcm PCM handle
4368  * \param params Configuration space
4369  * \param access Returned first access type
4370  * \return 0 otherwise a negative error code
4371  */
4372 #ifndef DOXYGEN
snd_pcm_hw_params_set_access_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_t *access)4373 EXPORT_SYMBOL int INTERNAL(snd_pcm_hw_params_set_access_first)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_t *access)
4374 #else
4375 int snd_pcm_hw_params_set_access_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_t *access)
4376 #endif
4377 {
4378 	return snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_ACCESS, access, NULL);
4379 }
4380 
4381 /**
4382  * \brief Restrict a configuration space to contain only its last access type
4383  * \param pcm PCM handle
4384  * \param params Configuration space
4385  * \param access Returned last access type
4386  * \return 0 otherwise a negative error code
4387  */
4388 #ifndef DOXYGEN
snd_pcm_hw_params_set_access_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_t *access)4389 EXPORT_SYMBOL int INTERNAL(snd_pcm_hw_params_set_access_last)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_t *access)
4390 #else
4391 int snd_pcm_hw_params_set_access_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_t *access)
4392 #endif
4393 {
4394 	return snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_ACCESS, access, NULL);
4395 }
4396 
4397 /**
4398  * \brief Restrict a configuration space to contain only a set of access types
4399  * \param pcm PCM handle
4400  * \param params Configuration space
4401  * \param mask Access mask
4402  * \return 0 otherwise a negative error code
4403  */
snd_pcm_hw_params_set_access_mask(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_mask_t *mask)4404 int snd_pcm_hw_params_set_access_mask(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_mask_t *mask)
4405 {
4406 	return snd_pcm_hw_param_set_mask(pcm, params, SND_TRY, SND_PCM_HW_PARAM_ACCESS, (snd_mask_t *) mask);
4407 }
4408 
4409 /**
4410  * \brief Get access mask from a configuration space
4411  * \param params Configuration space
4412  * \param mask Returned Access mask
4413  */
snd_pcm_hw_params_get_access_mask(snd_pcm_hw_params_t *params, snd_pcm_access_mask_t *mask)4414 int snd_pcm_hw_params_get_access_mask(snd_pcm_hw_params_t *params, snd_pcm_access_mask_t *mask)
4415 {
4416 	if (params == NULL || mask == NULL)
4417 		return -EINVAL;
4418 	snd_pcm_access_mask_copy(mask, snd_pcm_hw_param_get_mask(params, SND_PCM_HW_PARAM_ACCESS));
4419 	return 0;
4420 }
4421 
4422 
4423 /**
4424  * \brief Extract format from a configuration space
4425  * \param params Configuration space
4426  * \param format returned format
4427  * \return format otherwise a negative error code if the configuration space does not contain a single value
4428  */
4429 #ifndef DOXYGEN
snd_pcm_hw_params_get_format(const snd_pcm_hw_params_t *params, snd_pcm_format_t *format)4430 EXPORT_SYMBOL int INTERNAL(snd_pcm_hw_params_get_format)(const snd_pcm_hw_params_t *params, snd_pcm_format_t *format)
4431 #else
4432 int snd_pcm_hw_params_get_format(const snd_pcm_hw_params_t *params, snd_pcm_format_t *format)
4433 #endif
4434 {
4435 	return snd_pcm_hw_param_get(params, SND_PCM_HW_PARAM_FORMAT, (unsigned int *)format, NULL);
4436 }
4437 
4438 /**
4439  * \brief Verify if a format is available inside a configuration space for a PCM
4440  * \param pcm PCM handle
4441  * \param params Configuration space
4442  * \param format format
4443  * \return 0 if available a negative error code otherwise
4444  */
snd_pcm_hw_params_test_format(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_t format)4445 int snd_pcm_hw_params_test_format(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_t format)
4446 {
4447 	return snd_pcm_hw_param_set(pcm, params, SND_TEST, SND_PCM_HW_PARAM_FORMAT, format, 0);
4448 }
4449 
4450 /**
4451  * \brief Restrict a configuration space to contain only one format
4452  * \param pcm PCM handle
4453  * \param params Configuration space
4454  * \param format format
4455  * \return 0 otherwise a negative error code
4456  */
snd_pcm_hw_params_set_format(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_t format)4457 int snd_pcm_hw_params_set_format(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_t format)
4458 {
4459 	return snd_pcm_hw_param_set(pcm, params, SND_TRY, SND_PCM_HW_PARAM_FORMAT, format, 0);
4460 }
4461 
4462 /**
4463  * \brief Restrict a configuration space to contain only its first format
4464  * \param pcm PCM handle
4465  * \param params Configuration space
4466  * \param format Returned first format
4467  * \return 0 otherwise a negative error code
4468  */
4469 #ifndef DOXYGEN
snd_pcm_hw_params_set_format_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_t *format)4470 EXPORT_SYMBOL int INTERNAL(snd_pcm_hw_params_set_format_first)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_t *format)
4471 #else
4472 int snd_pcm_hw_params_set_format_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_t *format)
4473 #endif
4474 {
4475 	return snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_FORMAT, (unsigned int *)format, NULL);
4476 }
4477 
4478 /**
4479  * \brief Restrict a configuration space to contain only its last format
4480  * \param pcm PCM handle
4481  * \param params Configuration space
4482  * \param format Returned last format
4483  * \return 0 otherwise a negative error code
4484  */
4485 #ifndef DOXYGEN
snd_pcm_hw_params_set_format_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_t *format)4486 EXPORT_SYMBOL int INTERNAL(snd_pcm_hw_params_set_format_last)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_t *format)
4487 #else
4488 int snd_pcm_hw_params_set_format_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_t *format)
4489 #endif
4490 {
4491 	return snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_FORMAT, (unsigned int *)format, NULL);
4492 }
4493 
4494 /**
4495  * \brief Restrict a configuration space to contain only a set of formats
4496  * \param pcm PCM handle
4497  * \param params Configuration space
4498  * \param mask Format mask
4499  * \return 0 otherwise a negative error code
4500  */
snd_pcm_hw_params_set_format_mask(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_mask_t *mask)4501 int snd_pcm_hw_params_set_format_mask(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_mask_t *mask)
4502 {
4503 	return snd_pcm_hw_param_set_mask(pcm, params, SND_TRY, SND_PCM_HW_PARAM_FORMAT, (snd_mask_t *) mask);
4504 }
4505 
4506 /**
4507  * \brief Get format mask from a configuration space
4508  * \param params Configuration space
4509  * \param mask Returned Format mask
4510  */
snd_pcm_hw_params_get_format_mask(snd_pcm_hw_params_t *params, snd_pcm_format_mask_t *mask)4511 void snd_pcm_hw_params_get_format_mask(snd_pcm_hw_params_t *params, snd_pcm_format_mask_t *mask)
4512 {
4513 	snd_pcm_format_mask_copy(mask, snd_pcm_hw_param_get_mask(params, SND_PCM_HW_PARAM_FORMAT));
4514 }
4515 
4516 
4517 /**
4518  * \brief Extract subformat from a configuration space
4519  * \param params Configuration space
4520  * \param subformat Returned subformat value
4521  * \return subformat otherwise a negative error code if the configuration space does not contain a single value
4522  */
4523 #ifndef DOXYGEN
snd_pcm_hw_params_get_subformat(const snd_pcm_hw_params_t *params, snd_pcm_subformat_t *subformat)4524 EXPORT_SYMBOL int INTERNAL(snd_pcm_hw_params_get_subformat)(const snd_pcm_hw_params_t *params, snd_pcm_subformat_t *subformat)
4525 #else
4526 int snd_pcm_hw_params_get_subformat(const snd_pcm_hw_params_t *params, snd_pcm_subformat_t *subformat)
4527 #endif
4528 {
4529 	return snd_pcm_hw_param_get(params, SND_PCM_HW_PARAM_SUBFORMAT, (unsigned int *)subformat, NULL);
4530 }
4531 
4532 /**
4533  * \brief Verify if a subformat is available inside a configuration space for a PCM
4534  * \param pcm PCM handle
4535  * \param params Configuration space
4536  * \param subformat subformat value
4537  * \return 0 if available a negative error code otherwise
4538  */
snd_pcm_hw_params_test_subformat(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_t subformat)4539 int snd_pcm_hw_params_test_subformat(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_t subformat)
4540 {
4541 	return snd_pcm_hw_param_set(pcm, params, SND_TEST, SND_PCM_HW_PARAM_SUBFORMAT, subformat, 0);
4542 }
4543 
4544 /**
4545  * \brief Restrict a configuration space to contain only one subformat
4546  * \param pcm PCM handle
4547  * \param params Configuration space
4548  * \param subformat subformat value
4549  * \return 0 otherwise a negative error code if configuration space would become empty
4550  */
snd_pcm_hw_params_set_subformat(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_t subformat)4551 int snd_pcm_hw_params_set_subformat(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_t subformat)
4552 {
4553 	return snd_pcm_hw_param_set(pcm, params, SND_TRY, SND_PCM_HW_PARAM_SUBFORMAT, subformat, 0);
4554 }
4555 
4556 /**
4557  * \brief Restrict a configuration space to contain only its first subformat
4558  * \param pcm PCM handle
4559  * \param params Configuration space
4560  * \param subformat Returned subformat
4561  * \return 0 otherwise a negative error code
4562  */
4563 #ifndef DOXYGEN
snd_pcm_hw_params_set_subformat_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_t *subformat)4564 EXPORT_SYMBOL int INTERNAL(snd_pcm_hw_params_set_subformat_first)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_t *subformat)
4565 #else
4566 int snd_pcm_hw_params_set_subformat_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_t *subformat)
4567 #endif
4568 {
4569 	return snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_SUBFORMAT, (unsigned int *)subformat, NULL);
4570 }
4571 
4572 /**
4573  * \brief Restrict a configuration space to contain only its last subformat
4574  * \param pcm PCM handle
4575  * \param params Configuration space
4576  * \param subformat Returned subformat
4577  * \return 0 otherwise a negative error code
4578  */
4579 #ifndef DOXYGEN
snd_pcm_hw_params_set_subformat_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_t *subformat)4580 EXPORT_SYMBOL int INTERNAL(snd_pcm_hw_params_set_subformat_last)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_t *subformat)
4581 #else
4582 int snd_pcm_hw_params_set_subformat_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_t *subformat)
4583 #endif
4584 {
4585 	return snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_SUBFORMAT, (unsigned int *)subformat, NULL);
4586 }
4587 
4588 /**
4589  * \brief Restrict a configuration space to contain only a set of subformats
4590  * \param pcm PCM handle
4591  * \param params Configuration space
4592  * \param mask Subformat mask
4593  * \return 0 otherwise a negative error code
4594  */
snd_pcm_hw_params_set_subformat_mask(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_mask_t *mask)4595 int snd_pcm_hw_params_set_subformat_mask(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_mask_t *mask)
4596 {
4597 	return snd_pcm_hw_param_set_mask(pcm, params, SND_TRY, SND_PCM_HW_PARAM_SUBFORMAT, (snd_mask_t *) mask);
4598 }
4599 
4600 /**
4601  * \brief Get subformat mask from a configuration space
4602  * \param params Configuration space
4603  * \param mask Returned Subformat mask
4604  */
snd_pcm_hw_params_get_subformat_mask(snd_pcm_hw_params_t *params, snd_pcm_subformat_mask_t *mask)4605 void snd_pcm_hw_params_get_subformat_mask(snd_pcm_hw_params_t *params, snd_pcm_subformat_mask_t *mask)
4606 {
4607 	snd_pcm_subformat_mask_copy(mask, snd_pcm_hw_param_get_mask(params, SND_PCM_HW_PARAM_SUBFORMAT));
4608 }
4609 
4610 
4611 /**
4612  * \brief Extract channels from a configuration space
4613  * \param params Configuration space
4614  * \param val Returned channels count
4615  * \return 0 otherwise a negative error code if the configuration space does not contain a single value
4616  */
4617 #ifndef DOXYGEN
snd_pcm_hw_params_get_channels(const snd_pcm_hw_params_t *params, unsigned int *val)4618 EXPORT_SYMBOL int INTERNAL(snd_pcm_hw_params_get_channels)(const snd_pcm_hw_params_t *params, unsigned int *val)
4619 #else
4620 int snd_pcm_hw_params_get_channels(const snd_pcm_hw_params_t *params, unsigned int *val)
4621 #endif
4622 {
4623 	return snd_pcm_hw_param_get(params, SND_PCM_HW_PARAM_CHANNELS, val, NULL);
4624 }
4625 
4626 /**
4627  * \brief Extract minimum channels count from a configuration space
4628  * \param params Configuration space
4629  * \param val minimum channels count
4630  * \return 0 otherwise a negative error code
4631  */
4632 #ifndef DOXYGEN
snd_pcm_hw_params_get_channels_min(const snd_pcm_hw_params_t *params, unsigned int *val)4633 EXPORT_SYMBOL int INTERNAL(snd_pcm_hw_params_get_channels_min)(const snd_pcm_hw_params_t *params, unsigned int *val)
4634 #else
4635 int snd_pcm_hw_params_get_channels_min(const snd_pcm_hw_params_t *params, unsigned int *val)
4636 #endif
4637 {
4638 	return snd_pcm_hw_param_get_min(params, SND_PCM_HW_PARAM_CHANNELS, val, NULL);
4639 }
4640 
4641 /**
4642  * \brief Extract maximum channels count from a configuration space
4643  * \param params Configuration space
4644  * \param val maximum channels count
4645  * \return 0 otherwise a negative error code
4646  */
4647 #ifndef DOXYGEN
snd_pcm_hw_params_get_channels_max(const snd_pcm_hw_params_t *params, unsigned int *val)4648 EXPORT_SYMBOL int INTERNAL(snd_pcm_hw_params_get_channels_max)(const snd_pcm_hw_params_t *params, unsigned int *val)
4649 #else
4650 int snd_pcm_hw_params_get_channels_max(const snd_pcm_hw_params_t *params, unsigned int *val)
4651 #endif
4652 {
4653 	return snd_pcm_hw_param_get_max(params, SND_PCM_HW_PARAM_CHANNELS, val, NULL);
4654 }
4655 
4656 /**
4657  * \brief Verify if a channels count is available inside a configuration space for a PCM
4658  * \param pcm PCM handle
4659  * \param params Configuration space
4660  * \param val channels count
4661  * \return 0 if available a negative error code otherwise
4662  */
snd_pcm_hw_params_test_channels(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val)4663 int snd_pcm_hw_params_test_channels(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val)
4664 {
4665 	return snd_pcm_hw_param_set(pcm, params, SND_TEST, SND_PCM_HW_PARAM_CHANNELS, val, 0);
4666 }
4667 
4668 /**
4669  * \brief Restrict a configuration space to contain only one channels count
4670  * \param pcm PCM handle
4671  * \param params Configuration space
4672  * \param val channels count
4673  * \return 0 otherwise a negative error code if configuration space would become empty
4674  */
snd_pcm_hw_params_set_channels(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val)4675 int snd_pcm_hw_params_set_channels(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val)
4676 {
4677 	return snd_pcm_hw_param_set(pcm, params, SND_TRY, SND_PCM_HW_PARAM_CHANNELS, val, 0);
4678 }
4679 
4680 /**
4681  * \brief Restrict a configuration space with a minimum channels count
4682  * \param pcm PCM handle
4683  * \param params Configuration space
4684  * \param val minimum channels count (on return filled with actual minimum)
4685  * \return 0 otherwise a negative error code if configuration space would become empty
4686  */
snd_pcm_hw_params_set_channels_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val)4687 int snd_pcm_hw_params_set_channels_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val)
4688 {
4689 	return snd_pcm_hw_param_set_min(pcm, params, SND_TRY, SND_PCM_HW_PARAM_CHANNELS, val, NULL);
4690 }
4691 
4692 /**
4693  * \brief Restrict a configuration space with a maximum channels count
4694  * \param pcm PCM handle
4695  * \param params Configuration space
4696  * \param val maximum channels count (on return filled with actual maximum)
4697  * \return 0 otherwise a negative error code if configuration space would become empty
4698  */
snd_pcm_hw_params_set_channels_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val)4699 int snd_pcm_hw_params_set_channels_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val)
4700 {
4701 	return snd_pcm_hw_param_set_max(pcm, params, SND_TRY, SND_PCM_HW_PARAM_CHANNELS, val, NULL);
4702 }
4703 
4704 /**
4705  * \brief Restrict a configuration space to have channels counts in a given range
4706  * \param pcm PCM handle
4707  * \param params Configuration space
4708  * \param min minimum channels count (on return filled with actual minimum)
4709  * \param max maximum channels count (on return filled with actual maximum)
4710  * \return 0 otherwise a negative error code if configuration space would become empty
4711  */
snd_pcm_hw_params_set_channels_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *min, unsigned int *max)4712 int snd_pcm_hw_params_set_channels_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *min, unsigned int *max)
4713 {
4714 	return snd_pcm_hw_param_set_minmax(pcm, params, SND_TRY, SND_PCM_HW_PARAM_CHANNELS, min, NULL, max, NULL);
4715 }
4716 
4717 /**
4718  * \brief Restrict a configuration space to have channels count nearest to a target
4719  * \param pcm PCM handle
4720  * \param params Configuration space
4721  * \param val target channels count, returned chosen channels count
4722  * \return 0 otherwise a negative error code if configuration space is empty
4723  */
4724 #ifndef DOXYGEN
snd_pcm_hw_params_set_channels_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val)4725 EXPORT_SYMBOL int INTERNAL(snd_pcm_hw_params_set_channels_near)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val)
4726 #else
4727 int snd_pcm_hw_params_set_channels_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val)
4728 #endif
4729 {
4730 	return snd_pcm_hw_param_set_near(pcm, params, SND_PCM_HW_PARAM_CHANNELS, val, NULL);
4731 }
4732 
4733 /**
4734  * \brief Restrict a configuration space to contain only its minimum channels count
4735  * \param pcm PCM handle
4736  * \param params Configuration space
4737  * \param val minimum channels count
4738  * \return 0 otherwise a negative error code
4739  */
4740 #ifndef DOXYGEN
snd_pcm_hw_params_set_channels_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val)4741 EXPORT_SYMBOL int INTERNAL(snd_pcm_hw_params_set_channels_first)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val)
4742 #else
4743 int snd_pcm_hw_params_set_channels_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val)
4744 #endif
4745 {
4746 	return snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_CHANNELS, val, NULL);
4747 }
4748 
4749 /**
4750  * \brief Restrict a configuration space to contain only its maximum channels count
4751  * \param pcm PCM handle
4752  * \param params Configuration space
4753  * \param val maximum channels count
4754  * \return 0 otherwise a negative error code
4755  */
4756 #ifndef DOXYGEN
snd_pcm_hw_params_set_channels_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val)4757 EXPORT_SYMBOL int INTERNAL(snd_pcm_hw_params_set_channels_last)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val)
4758 #else
4759 int snd_pcm_hw_params_set_channels_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val)
4760 #endif
4761 {
4762 	return snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_CHANNELS, val, NULL);
4763 }
4764 
4765 
4766 /**
4767  * \brief Extract rate from a configuration space
4768  * \param params Configuration space
4769  * \param val Returned approximate rate
4770  * \param dir Sub unit direction
4771  * \return 0 otherwise a negative error code if the configuration space does not contain a single value
4772  *
4773  * Actual exact value is <,=,> the approximate one following dir (-1, 0, 1)
4774  */
4775 #ifndef DOXYGEN
snd_pcm_hw_params_get_rate(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)4776 EXPORT_SYMBOL int INTERNAL(snd_pcm_hw_params_get_rate)(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4777 #else
4778 int snd_pcm_hw_params_get_rate(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4779 #endif
4780 {
4781 	return snd_pcm_hw_param_get(params, SND_PCM_HW_PARAM_RATE, val, dir);
4782 }
4783 
4784 /**
4785  * \brief Extract minimum rate from a configuration space
4786  * \param params Configuration space
4787  * \param val Returned approximate minimum rate
4788  * \param dir Sub unit direction
4789  * \return 0 otherwise a negative error code
4790  *
4791  * Exact value is <,=,> the returned one following dir (-1,0,1)
4792  */
4793 #ifndef DOXYGEN
snd_pcm_hw_params_get_rate_min(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)4794 EXPORT_SYMBOL int INTERNAL(snd_pcm_hw_params_get_rate_min)(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4795 #else
4796 int snd_pcm_hw_params_get_rate_min(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4797 #endif
4798 {
4799 	return snd_pcm_hw_param_get_min(params, SND_PCM_HW_PARAM_RATE, val, dir);
4800 }
4801 
4802 /**
4803  * \brief Extract maximum rate from a configuration space
4804  * \param params Configuration space
4805  * \param val Returned approximate maximum rate
4806  * \param dir Sub unit direction
4807  * \return 0 otherwise a negative error code
4808  *
4809  * Exact value is <,=,> the returned one following dir (-1,0,1)
4810  */
4811 #ifndef DOXYGEN
snd_pcm_hw_params_get_rate_max(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)4812 EXPORT_SYMBOL int INTERNAL(snd_pcm_hw_params_get_rate_max)(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4813 #else
4814 int snd_pcm_hw_params_get_rate_max(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4815 #endif
4816 {
4817 	return snd_pcm_hw_param_get_max(params, SND_PCM_HW_PARAM_RATE, val, dir);
4818 }
4819 
4820 /**
4821  * \brief Verify if a rate is available inside a configuration space for a PCM
4822  * \param pcm PCM handle
4823  * \param params Configuration space
4824  * \param val approximate rate
4825  * \param dir Sub unit direction
4826  * \return 0 if available a negative error code otherwise
4827  *
4828  * Wanted exact value is <,=,> val following dir (-1,0,1)
4829  */
snd_pcm_hw_params_test_rate(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir)4830 int snd_pcm_hw_params_test_rate(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir)
4831 {
4832 	return snd_pcm_hw_param_set(pcm, params, SND_TEST, SND_PCM_HW_PARAM_RATE, val, dir);
4833 }
4834 
4835 /**
4836  * \brief Restrict a configuration space to contain only one rate
4837  * \param pcm PCM handle
4838  * \param params Configuration space
4839  * \param val approximate rate
4840  * \param dir Sub unit direction
4841  * \return 0 otherwise a negative error code if configuration space would become empty
4842  *
4843  * Wanted exact value is <,=,> val following dir (-1,0,1)
4844  */
snd_pcm_hw_params_set_rate(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir)4845 int snd_pcm_hw_params_set_rate(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir)
4846 {
4847 	return snd_pcm_hw_param_set(pcm, params, SND_TRY, SND_PCM_HW_PARAM_RATE, val, dir);
4848 }
4849 
4850 /**
4851  * \brief Restrict a configuration space with a minimum rate
4852  * \param pcm PCM handle
4853  * \param params Configuration space
4854  * \param val approximate minimum rate (on return filled with actual minimum)
4855  * \param dir Sub unit direction (on return filled with actual direction)
4856  * \return 0 otherwise a negative error code if configuration space would become empty
4857  *
4858  * Wanted/actual exact minimum is <,=,> val following dir (-1,0,1)
4859  */
snd_pcm_hw_params_set_rate_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)4860 int snd_pcm_hw_params_set_rate_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4861 {
4862 	return snd_pcm_hw_param_set_min(pcm, params, SND_TRY, SND_PCM_HW_PARAM_RATE, val, dir);
4863 }
4864 
4865 /**
4866  * \brief Restrict a configuration space with a maximum rate
4867  * \param pcm PCM handle
4868  * \param params Configuration space
4869  * \param val approximate maximum rate (on return filled with actual maximum)
4870  * \param dir Sub unit direction (on return filled with actual direction)
4871  * \return 0 otherwise a negative error code if configuration space would become empty
4872  *
4873  * Wanted/actual exact maximum is <,=,> val following dir (-1,0,1)
4874  */
snd_pcm_hw_params_set_rate_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)4875 int snd_pcm_hw_params_set_rate_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4876 {
4877 	return snd_pcm_hw_param_set_max(pcm, params, SND_TRY, SND_PCM_HW_PARAM_RATE, val, dir);
4878 }
4879 
4880 /**
4881  * \brief Restrict a configuration space to have rates in a given range
4882  * \param pcm PCM handle
4883  * \param params Configuration space
4884  * \param min approximate minimum rate (on return filled with actual minimum)
4885  * \param mindir Sub unit direction for minimum (on return filled with actual direction)
4886  * \param max approximate maximum rate (on return filled with actual maximum)
4887  * \param maxdir Sub unit direction for maximum (on return filled with actual direction)
4888  * \return 0 otherwise a negative error code if configuration space would become empty
4889  *
4890  * Wanted/actual exact min/max is <,=,> val following dir (-1,0,1)
4891  */
snd_pcm_hw_params_set_rate_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *min, int *mindir, unsigned int *max, int *maxdir)4892 int snd_pcm_hw_params_set_rate_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *min, int *mindir, unsigned int *max, int *maxdir)
4893 {
4894 	return snd_pcm_hw_param_set_minmax(pcm, params, SND_TRY, SND_PCM_HW_PARAM_RATE, min, mindir, max, maxdir);
4895 }
4896 
4897 /**
4898  * \brief Restrict a configuration space to have rate nearest to a target
4899  * \param pcm PCM handle
4900  * \param params Configuration space
4901  * \param val approximate target rate / returned approximate set rate
4902  * \param dir Sub unit direction
4903  * \return 0 otherwise a negative error code if configuration space is empty
4904  *
4905  * target/chosen exact value is <,=,> val following dir (-1,0,1)
4906  */
4907 #ifndef DOXYGEN
snd_pcm_hw_params_set_rate_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)4908 EXPORT_SYMBOL int INTERNAL(snd_pcm_hw_params_set_rate_near)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4909 #else
4910 int snd_pcm_hw_params_set_rate_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4911 #endif
4912 {
4913 	return snd_pcm_hw_param_set_near(pcm, params, SND_PCM_HW_PARAM_RATE, val, dir);
4914 }
4915 
4916 /**
4917  * \brief Restrict a configuration space to contain only its minimum rate
4918  * \param pcm PCM handle
4919  * \param params Configuration space
4920  * \param val Returned minimum approximate rate
4921  * \param dir Sub unit direction
4922  * \return 0 otherwise a negative error code
4923  *
4924  * Actual exact value is <,=,> the approximate one following dir (-1, 0, 1)
4925  */
4926 #ifndef DOXYGEN
snd_pcm_hw_params_set_rate_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)4927 EXPORT_SYMBOL int INTERNAL(snd_pcm_hw_params_set_rate_first)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4928 #else
4929 int snd_pcm_hw_params_set_rate_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4930 #endif
4931 {
4932 	return snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_RATE, val, dir);
4933 }
4934 
4935 /**
4936  * \brief Restrict a configuration space to contain only its maximum rate
4937  * \param pcm PCM handle
4938  * \param params Configuration space
4939  * \param val Returned maximum approximate rate
4940  * \param dir Sub unit direction
4941  * \return 0 otherwise a negative error code
4942  *
4943  * Actual exact value is <,=,> the approximate one following dir (-1, 0, 1)
4944  */
4945 #ifndef DOXYGEN
snd_pcm_hw_params_set_rate_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)4946 EXPORT_SYMBOL int INTERNAL(snd_pcm_hw_params_set_rate_last)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4947 #else
4948 int snd_pcm_hw_params_set_rate_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4949 #endif
4950 {
4951 	return snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_RATE, val, dir);
4952 }
4953 
4954 /**
4955  * \brief Restrict a configuration space to contain only real hardware rates
4956  * \param pcm PCM handle
4957  * \param params Configuration space
4958  * \param val 0 = disable, 1 = enable (default) rate resampling
4959  * \return 0 otherwise a negative error code
4960  */
snd_pcm_hw_params_set_rate_resample(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val)4961 int snd_pcm_hw_params_set_rate_resample(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val)
4962 {
4963 	assert(pcm && params);
4964 	if (!val)
4965 		params->flags |= SND_PCM_HW_PARAMS_NORESAMPLE;
4966 	else
4967 		params->flags &= ~SND_PCM_HW_PARAMS_NORESAMPLE;
4968 	params->rmask = ~0;
4969 	return snd_pcm_hw_refine(pcm, params);
4970 }
4971 
4972 /**
4973  * \brief Extract resample state from a configuration space
4974  * \param pcm PCM handle
4975  * \param params Configuration space
4976  * \param val 0 = disable, 1 = enable rate resampling
4977  * \return 0 otherwise a negative error code
4978  */
snd_pcm_hw_params_get_rate_resample(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val)4979 int snd_pcm_hw_params_get_rate_resample(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val)
4980 {
4981 	assert(pcm && params && val);
4982 	*val = params->flags & SND_PCM_HW_PARAMS_NORESAMPLE ? 0 : 1;
4983 	return 0;
4984 }
4985 
4986 /**
4987  * \brief Restrict a configuration space to allow the buffer to be accessible from outside
4988  * \param pcm PCM handle
4989  * \param params Configuration space
4990  * \param val 0 = disable, 1 = enable (default) exporting buffer
4991  * \return 0 otherwise a negative error code
4992  */
snd_pcm_hw_params_set_export_buffer(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val)4993 int snd_pcm_hw_params_set_export_buffer(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val)
4994 {
4995 	assert(pcm && params);
4996 	if (val)
4997 		params->flags |= SND_PCM_HW_PARAMS_EXPORT_BUFFER;
4998 	else
4999 		params->flags &= ~SND_PCM_HW_PARAMS_EXPORT_BUFFER;
5000 	params->rmask = ~0;
5001 	return snd_pcm_hw_refine(pcm, params);
5002 }
5003 
5004 /**
5005  * \brief Extract buffer accessibility from a configuration space
5006  * \param pcm PCM handle
5007  * \param params Configuration space
5008  * \param val 0 = disable, 1 = enable exporting buffer
5009  * \return 0 otherwise a negative error code
5010  */
snd_pcm_hw_params_get_export_buffer(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val)5011 int snd_pcm_hw_params_get_export_buffer(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val)
5012 {
5013 	assert(pcm && params && val);
5014 	*val = params->flags & SND_PCM_HW_PARAMS_EXPORT_BUFFER ? 1 : 0;
5015 	return 0;
5016 }
5017 
5018 /**
5019  * \brief Restrict a configuration space to settings without period wakeups
5020  * \param pcm PCM handle
5021  * \param params Configuration space
5022  * \param val 0 = disable, 1 = enable (default) period wakeup
5023  * \return Zero on success, otherwise a negative error code.
5024  *
5025  * This function must be called only on devices where non-blocking mode is
5026  * enabled.
5027  *
5028  * To check whether the hardware does support disabling period wakeups, call
5029  * #snd_pcm_hw_params_can_disable_period_wakeup(). If the hardware does not
5030  * support this mode, standard period wakeups will be generated.
5031  *
5032  * Even with disabled period wakeups, the period size/time/count parameters
5033  * are valid; it is suggested to use #snd_pcm_hw_params_set_period_size_last().
5034  *
5035  * When period wakeups are disabled, the application must not use any functions
5036  * that could block on this device. The use of poll should be limited to error
5037  * cases. The application needs to use an external event or a timer to
5038  * check the state of the ring buffer and refill it apropriately.
5039  */
snd_pcm_hw_params_set_period_wakeup(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val)5040 int snd_pcm_hw_params_set_period_wakeup(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val)
5041 {
5042 	assert(pcm && params);
5043 
5044 	if (!val) {
5045 		if (!(pcm->mode & SND_PCM_NONBLOCK))
5046 			return -EINVAL;
5047 		params->flags |= SND_PCM_HW_PARAMS_NO_PERIOD_WAKEUP;
5048 	} else
5049 		params->flags &= ~SND_PCM_HW_PARAMS_NO_PERIOD_WAKEUP;
5050 	params->rmask = ~0;
5051 
5052 	return snd_pcm_hw_refine(pcm, params);
5053 }
5054 
5055 /**
5056  * \brief Extract period wakeup flag from a configuration space
5057  * \param pcm PCM handle
5058  * \param params Configuration space
5059  * \param val 0 = disabled, 1 = enabled period wakeups
5060  * \return Zero on success, otherwise a negative error code.
5061  */
snd_pcm_hw_params_get_period_wakeup(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val)5062 int snd_pcm_hw_params_get_period_wakeup(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val)
5063 {
5064 	assert(pcm && params && val);
5065 	*val = params->flags & SND_PCM_HW_PARAMS_NO_PERIOD_WAKEUP ? 0 : 1;
5066 	return 0;
5067 }
5068 
5069 /**
5070  * \brief Restrict a configuration space to fill the end of playback stream with silence when drain() is invoked
5071  * \param pcm PCM handle
5072  * \param params Configuration space
5073  * \param val 0 = disabled, 1 = enabled (default) fill the end of the playback stream with silence when drain() is invoked
5074  * \return Zero on success, otherwise a negative error code.
5075  *
5076  * When disabled, the application should handle the end of stream gracefully
5077  * (fill the silent samples to align to the period size plus some extra
5078  * samples for hardware / driver without perfect drain). Note that the rewind
5079  * may be used for this purpose or the sw_params silencing mechanism.
5080  */
snd_pcm_hw_params_set_drain_silence(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val)5081 int snd_pcm_hw_params_set_drain_silence(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val)
5082 {
5083 	assert(pcm && params);
5084 	if (val)
5085 		params->flags &= ~SND_PCM_HW_PARAMS_NO_DRAIN_SILENCE;
5086 	else
5087 		params->flags |= SND_PCM_HW_PARAMS_NO_DRAIN_SILENCE;
5088 	params->rmask = ~0;
5089 	return snd_pcm_hw_refine(pcm, params);
5090 }
5091 
5092 /**
5093  * \brief Extract drain with the filling of silence samples from a configuration space
5094  * \param pcm PCM handle
5095  * \param params Configuration space
5096  * \param val 0 = disabled, 1 = enabled
5097  * \return 0 otherwise a negative error code
5098  */
snd_pcm_hw_params_get_drain_silence(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val)5099 int snd_pcm_hw_params_get_drain_silence(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val)
5100 {
5101 	assert(pcm && params && val);
5102 	*val = params->flags & SND_PCM_HW_PARAMS_NO_DRAIN_SILENCE ? 0 : 1;
5103 	return 0;
5104 }
5105 
5106 /**
5107  * \brief Extract period time from a configuration space
5108  * \param params Configuration space
5109  * \param val Returned approximate period duration in us
5110  * \param dir Sub unit direction
5111  * \return 0 otherwise a negative error code if the configuration space does not contain a single value
5112  *
5113  * Actual exact value is <,=,> the approximate one following dir (-1, 0, 1)
5114  */
5115 #ifndef DOXYGEN
snd_pcm_hw_params_get_period_time(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)5116 EXPORT_SYMBOL int INTERNAL(snd_pcm_hw_params_get_period_time)(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
5117 #else
5118 int snd_pcm_hw_params_get_period_time(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
5119 #endif
5120 {
5121 	return snd_pcm_hw_param_get(params, SND_PCM_HW_PARAM_PERIOD_TIME, val, dir);
5122 }
5123 
5124 /**
5125  * \brief Extract minimum period time from a configuration space
5126  * \param params Configuration space
5127  * \param val approximate minimum period duration in us
5128  * \param dir Sub unit direction
5129  * \return 0 otherwise a negative error code
5130  *
5131  * Exact value is <,=,> the returned one following dir (-1,0,1)
5132  */
5133 #ifndef DOXYGEN
snd_pcm_hw_params_get_period_time_min(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)5134 EXPORT_SYMBOL int INTERNAL(snd_pcm_hw_params_get_period_time_min)(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
5135 #else
5136 int snd_pcm_hw_params_get_period_time_min(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
5137 #endif
5138 {
5139 	return snd_pcm_hw_param_get_min(params, SND_PCM_HW_PARAM_PERIOD_TIME, val, dir);
5140 }
5141 
5142 /**
5143  * \brief Extract maximum period time from a configuration space
5144  * \param params Configuration space
5145  * \param val approximate maximum period duration in us
5146  * \param dir Sub unit direction
5147  * \return 0 otherwise a negative error code
5148  *
5149  * Exact value is <,=,> the returned one following dir (-1,0,1)
5150  */
5151 #ifndef DOXYGEN
snd_pcm_hw_params_get_period_time_max(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)5152 EXPORT_SYMBOL int INTERNAL(snd_pcm_hw_params_get_period_time_max)(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
5153 #else
5154 int snd_pcm_hw_params_get_period_time_max(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
5155 #endif
5156 {
5157 	return snd_pcm_hw_param_get_max(params, SND_PCM_HW_PARAM_PERIOD_TIME, val, dir);
5158 }
5159 
5160 /**
5161  * \brief Verify if a period time is available inside a configuration space for a PCM
5162  * \param pcm PCM handle
5163  * \param params Configuration space
5164  * \param val approximate period duration in us
5165  * \param dir Sub unit direction
5166  * \return 0 if available a negative error code otherwise
5167  *
5168  * Wanted exact value is <,=,> val following dir (-1,0,1)
5169  */
snd_pcm_hw_params_test_period_time(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir)5170 int snd_pcm_hw_params_test_period_time(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir)
5171 {
5172 	return snd_pcm_hw_param_set(pcm, params, SND_TEST, SND_PCM_HW_PARAM_PERIOD_TIME, val, dir);
5173 }
5174 
5175 /**
5176  * \brief Restrict a configuration space to contain only one period time
5177  * \param pcm PCM handle
5178  * \param params Configuration space
5179  * \param val approximate period duration in us
5180  * \param dir Sub unit direction
5181  * \return 0 otherwise a negative error code if configuration space would become empty
5182  *
5183  * Wanted exact value is <,=,> val following dir (-1,0,1)
5184  */
snd_pcm_hw_params_set_period_time(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir)5185 int snd_pcm_hw_params_set_period_time(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir)
5186 {
5187 	return snd_pcm_hw_param_set(pcm, params, SND_TRY, SND_PCM_HW_PARAM_PERIOD_TIME, val, dir);
5188 }
5189 
5190 
5191 /**
5192  * \brief Restrict a configuration space with a minimum period time
5193  * \param pcm PCM handle
5194  * \param params Configuration space
5195  * \param val approximate minimum period duration in us (on return filled with actual minimum)
5196  * \param dir Sub unit direction (on return filled with actual direction)
5197  * \return 0 otherwise a negative error code if configuration space would become empty
5198  *
5199  * Wanted/actual exact minimum is <,=,> val following dir (-1,0,1)
5200  */
snd_pcm_hw_params_set_period_time_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)5201 int snd_pcm_hw_params_set_period_time_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
5202 {
5203 	return snd_pcm_hw_param_set_min(pcm, params, SND_TRY, SND_PCM_HW_PARAM_PERIOD_TIME, val, dir);
5204 }
5205 
5206 /**
5207  * \brief Restrict a configuration space with a maximum period time
5208  * \param pcm PCM handle
5209  * \param params Configuration space
5210  * \param val approximate maximum period duration in us (on return filled with actual maximum)
5211  * \param dir Sub unit direction (on return filled with actual direction)
5212  * \return 0 otherwise a negative error code if configuration space would become empty
5213  *
5214  * Wanted/actual exact maximum is <,=,> val following dir (-1,0,1)
5215  */
snd_pcm_hw_params_set_period_time_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)5216 int snd_pcm_hw_params_set_period_time_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
5217 {
5218 	return snd_pcm_hw_param_set_max(pcm, params, SND_TRY, SND_PCM_HW_PARAM_PERIOD_TIME, val, dir);
5219 }
5220 
5221 /**
5222  * \brief Restrict a configuration space to have period times in a given range
5223  * \param pcm PCM handle
5224  * \param params Configuration space
5225  * \param min approximate minimum period duration in us (on return filled with actual minimum)
5226  * \param mindir Sub unit direction for minimum (on return filled with actual direction)
5227  * \param max approximate maximum period duration in us (on return filled with actual maximum)
5228  * \param maxdir Sub unit direction for maximum (on return filled with actual direction)
5229  * \return 0 otherwise a negative error code if configuration space would become empty
5230  *
5231  * Wanted/actual exact min/max is <,=,> val following dir (-1,0,1)
5232  */
snd_pcm_hw_params_set_period_time_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *min, int *mindir, unsigned int *max, int *maxdir)5233 int snd_pcm_hw_params_set_period_time_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *min, int *mindir, unsigned int *max, int *maxdir)
5234 {
5235 	return snd_pcm_hw_param_set_minmax(pcm, params, SND_TRY, SND_PCM_HW_PARAM_PERIOD_TIME, min, mindir, max, maxdir);
5236 }
5237 
5238 /**
5239  * \brief Restrict a configuration space to have period time nearest to a target
5240  * \param pcm PCM handle
5241  * \param params Configuration space
5242  * \param val approximate target period duration in us / returned chosen approximate target period duration
5243  * \param dir Sub unit direction
5244  * \return 0 otherwise a negative error code if configuration space is empty
5245  *
5246  * target/chosen exact value is <,=,> val following dir (-1,0,1)
5247  */
5248 #ifndef DOXYGEN
snd_pcm_hw_params_set_period_time_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)5249 EXPORT_SYMBOL int INTERNAL(snd_pcm_hw_params_set_period_time_near)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
5250 #else
5251 int snd_pcm_hw_params_set_period_time_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
5252 #endif
5253 {
5254 	return snd_pcm_hw_param_set_near(pcm, params, SND_PCM_HW_PARAM_PERIOD_TIME, val, dir);
5255 }
5256 
5257 /**
5258  * \brief Restrict a configuration space to contain only its minimum period time
5259  * \param pcm PCM handle
5260  * \param params Configuration space
5261  * \param val Returned approximate period duration in us
5262  * \param dir Sub unit direction
5263  * \return 0 otherwise a negative error code
5264  *
5265  * Actual exact value is <,=,> the approximate one following dir (-1, 0, 1)
5266  */
5267 #ifndef DOXYGEN
snd_pcm_hw_params_set_period_time_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)5268 EXPORT_SYMBOL int INTERNAL(snd_pcm_hw_params_set_period_time_first)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
5269 #else
5270 int snd_pcm_hw_params_set_period_time_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
5271 #endif
5272 {
5273 	return snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_PERIOD_TIME, val, dir);
5274 }
5275 
5276 /**
5277  * \brief Restrict a configuration space to contain only its maximum period time
5278  * \param pcm PCM handle
5279  * \param params Configuration space
5280  * \param val Returned maximum approximate period time
5281  * \param dir Sub unit direction
5282  * \return approximate period duration in us
5283  */
5284 #ifndef DOXYGEN
snd_pcm_hw_params_set_period_time_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)5285 EXPORT_SYMBOL int INTERNAL(snd_pcm_hw_params_set_period_time_last)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
5286 #else
5287 int snd_pcm_hw_params_set_period_time_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
5288 #endif
5289 {
5290 	return snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_PERIOD_TIME, val, dir);
5291 }
5292 
5293 
5294 /**
5295  * \brief Extract period size from a configuration space
5296  * \param params Configuration space
5297  * \param val Returned approximate period size in frames
5298  * \param dir Sub unit direction
5299  * \return 0 otherwise a negative error code if the configuration space does not contain a single value
5300  *
5301  * Actual exact value is <,=,> the approximate one following dir (-1, 0, 1)
5302  */
5303 #ifndef DOXYGEN
snd_pcm_hw_params_get_period_size(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir)5304 EXPORT_SYMBOL int INTERNAL(snd_pcm_hw_params_get_period_size)(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir)
5305 #else
5306 int snd_pcm_hw_params_get_period_size(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir)
5307 #endif
5308 {
5309 	unsigned int _val;
5310 	int err = snd_pcm_hw_param_get(params, SND_PCM_HW_PARAM_PERIOD_SIZE, &_val, dir);
5311 	if (err >= 0)
5312 		*val = _val;
5313 	return err;
5314 }
5315 
5316 /**
5317  * \brief Extract minimum period size from a configuration space
5318  * \param params Configuration space
5319  * \param val approximate minimum period size in frames
5320  * \param dir Sub unit direction
5321  * \return 0 otherwise a negative error code
5322  *
5323  * Exact value is <,=,> the returned one following dir (-1,0,1)
5324  */
5325 #ifndef DOXYGEN
snd_pcm_hw_params_get_period_size_min(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir)5326 EXPORT_SYMBOL int INTERNAL(snd_pcm_hw_params_get_period_size_min)(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir)
5327 #else
5328 int snd_pcm_hw_params_get_period_size_min(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir)
5329 #endif
5330 {
5331 	unsigned int _val = *val;
5332 	int err = snd_pcm_hw_param_get_min(params, SND_PCM_HW_PARAM_PERIOD_SIZE, &_val, dir);
5333 	if (err >= 0)
5334 		*val = _val;
5335 	return err;
5336 }
5337 
5338 /**
5339  * \brief Extract maximum period size from a configuration space
5340  * \param params Configuration space
5341  * \param val approximate minimum period size in frames
5342  * \param dir Sub unit direction
5343  * \return 0 otherwise a negative error code
5344  *
5345  * Exact value is <,=,> the returned one following dir (-1,0,1)
5346  */
5347 #ifndef DOXYGEN
snd_pcm_hw_params_get_period_size_max(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir)5348 EXPORT_SYMBOL int INTERNAL(snd_pcm_hw_params_get_period_size_max)(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir)
5349 #else
5350 int snd_pcm_hw_params_get_period_size_max(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir)
5351 #endif
5352 {
5353 	unsigned int _val = *val;
5354 	int err = snd_pcm_hw_param_get_max(params, SND_PCM_HW_PARAM_PERIOD_SIZE, &_val, dir);
5355 	if (err >= 0)
5356 		*val = _val;
5357 	return err;
5358 }
5359 
5360 /**
5361  * \brief Verify if a period size is available inside a configuration space for a PCM
5362  * \param pcm PCM handle
5363  * \param params Configuration space
5364  * \param val approximate period size in frames
5365  * \param dir Sub unit direction
5366  * \return 0 if available a negative error code otherwise
5367  *
5368  * Wanted exact value is <,=,> val following dir (-1,0,1)
5369  */
snd_pcm_hw_params_test_period_size(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val, int dir)5370 int snd_pcm_hw_params_test_period_size(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val, int dir)
5371 {
5372 	return snd_pcm_hw_param_set(pcm, params, SND_TEST, SND_PCM_HW_PARAM_PERIOD_SIZE, val, dir);
5373 }
5374 
5375 /**
5376  * \brief Restrict a configuration space to contain only one period size
5377  * \param pcm PCM handle
5378  * \param params Configuration space
5379  * \param val approximate period size in frames
5380  * \param dir Sub unit direction
5381  * \return 0 otherwise a negative error code if configuration space would become empty
5382  *
5383  * Wanted exact value is <,=,> val following dir (-1,0,1)
5384  */
snd_pcm_hw_params_set_period_size(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val, int dir)5385 int snd_pcm_hw_params_set_period_size(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val, int dir)
5386 {
5387 	return snd_pcm_hw_param_set(pcm, params, SND_TRY, SND_PCM_HW_PARAM_PERIOD_SIZE, val, dir);
5388 }
5389 
5390 /**
5391  * \brief Restrict a configuration space with a minimum period size
5392  * \param pcm PCM handle
5393  * \param params Configuration space
5394  * \param val approximate minimum period size in frames (on return filled with actual minimum)
5395  * \param dir Sub unit direction (on return filled with actual direction)
5396  * \return 0 otherwise a negative error code if configuration space would become empty
5397  *
5398  * Wanted/actual exact minimum is <,=,> val following dir (-1,0,1)
5399  */
snd_pcm_hw_params_set_period_size_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir)5400 int snd_pcm_hw_params_set_period_size_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir)
5401 {
5402 	unsigned int _val = *val;
5403 	int err = snd_pcm_hw_param_set_min(pcm, params, SND_TRY, SND_PCM_HW_PARAM_PERIOD_SIZE, &_val, dir);
5404 	if (err >= 0)
5405 		*val = _val;
5406 	return err;
5407 }
5408 
5409 /**
5410  * \brief Restrict a configuration space with a maximum period size
5411  * \param pcm PCM handle
5412  * \param params Configuration space
5413  * \param val approximate maximum period size in frames (on return filled with actual maximum)
5414  * \param dir Sub unit direction (on return filled with actual direction)
5415  * \return 0 otherwise a negative error code if configuration space would become empty
5416  *
5417  * Wanted/actual exact minimum is <,=,> val following dir (-1,0,1)
5418  */
snd_pcm_hw_params_set_period_size_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir)5419 int snd_pcm_hw_params_set_period_size_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir)
5420 {
5421 	unsigned int _val = *val;
5422 	int err = snd_pcm_hw_param_set_max(pcm, params, SND_TRY, SND_PCM_HW_PARAM_PERIOD_SIZE, &_val, dir);
5423 	if (err >= 0)
5424 		*val = _val;
5425 	return err;
5426 }
5427 
5428 /**
5429  * \brief Restrict a configuration space to have period sizes in a given range
5430  * \param pcm PCM handle
5431  * \param params Configuration space
5432  * \param min approximate minimum period size in frames (on return filled with actual minimum)
5433  * \param mindir Sub unit direction for minimum (on return filled with actual direction)
5434  * \param max approximate maximum period size in frames (on return filled with actual maximum)
5435  * \param maxdir Sub unit direction for maximum (on return filled with actual direction)
5436  * \return 0 otherwise a negative error code if configuration space would become empty
5437  *
5438  * Wanted/actual exact min/max is <,=,> val following dir (-1,0,1)
5439  */
snd_pcm_hw_params_set_period_size_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *min, int *mindir, snd_pcm_uframes_t *max, int *maxdir)5440 int snd_pcm_hw_params_set_period_size_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *min, int *mindir, snd_pcm_uframes_t *max, int *maxdir)
5441 {
5442 	unsigned int _min = *min;
5443 	unsigned int _max = *max;
5444 	int err = snd_pcm_hw_param_set_minmax(pcm, params, SND_TRY, SND_PCM_HW_PARAM_PERIOD_SIZE, &_min, mindir, &_max, maxdir);
5445 	*min = _min;
5446 	*max = _max;
5447 	return err;
5448 }
5449 
5450 /**
5451  * \brief Restrict a configuration space to have period size nearest to a target
5452  * \param pcm PCM handle
5453  * \param params Configuration space
5454  * \param val approximate target period size in frames / returned chosen approximate target period size
5455  * \param dir Sub unit direction
5456  * \return 0 otherwise a negative error code if configuration space is empty
5457  *
5458  * target/chosen exact value is <,=,> val following dir (-1,0,1)
5459  */
5460 #ifndef DOXYGEN
snd_pcm_hw_params_set_period_size_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir)5461 EXPORT_SYMBOL int INTERNAL(snd_pcm_hw_params_set_period_size_near)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir)
5462 #else
5463 int snd_pcm_hw_params_set_period_size_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir)
5464 #endif
5465 {
5466 	unsigned int _val = *val;
5467 	int err = snd_pcm_hw_param_set_near(pcm, params, SND_PCM_HW_PARAM_PERIOD_SIZE, &_val, dir);
5468 	if (err >= 0)
5469 		*val = _val;
5470 	return err;
5471 }
5472 
5473 /**
5474  * \brief Restrict a configuration space to contain only its minimum period size
5475  * \param pcm PCM handle
5476  * \param params Configuration space
5477  * \param val Returned maximum approximate period size in frames
5478  * \param dir Sub unit direction
5479  * \return 0 otherwise a negative error code
5480  *
5481  * Actual exact value is <,=,> the approximate one following dir (-1, 0, 1)
5482  */
5483 #ifndef DOXYGEN
snd_pcm_hw_params_set_period_size_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir)5484 EXPORT_SYMBOL int INTERNAL(snd_pcm_hw_params_set_period_size_first)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir)
5485 #else
5486 int snd_pcm_hw_params_set_period_size_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir)
5487 #endif
5488 {
5489 	unsigned int _val;
5490 	int err = snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_PERIOD_SIZE, &_val, dir);
5491 	if (err >= 0)
5492 		*val = _val;
5493 	return err;
5494 }
5495 
5496 /**
5497  * \brief Restrict a configuration space to contain only its maximum period size
5498  * \param pcm PCM handle
5499  * \param params Configuration space
5500  * \param val Returned maximum approximate period size in frames
5501  * \param dir Sub unit direction
5502  * \return 0 otherwise a negative error code
5503  *
5504  * Actual exact value is <,=,> the approximate one following dir (-1, 0, 1)
5505  */
5506 #ifndef DOXYGEN
snd_pcm_hw_params_set_period_size_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir)5507 EXPORT_SYMBOL int INTERNAL(snd_pcm_hw_params_set_period_size_last)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir)
5508 #else
5509 int snd_pcm_hw_params_set_period_size_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir)
5510 #endif
5511 {
5512 	unsigned int _val;
5513 	int err = snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_PERIOD_SIZE, &_val, dir);
5514 	if (err >= 0)
5515 		*val = _val;
5516 	return err;
5517 }
5518 
5519 /**
5520  * \brief Restrict a configuration space to contain only integer period sizes
5521  * \param pcm PCM handle
5522  * \param params Configuration space
5523  * \return 0 otherwise a negative error code if configuration space would become empty
5524  */
snd_pcm_hw_params_set_period_size_integer(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)5525 int snd_pcm_hw_params_set_period_size_integer(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
5526 {
5527 	return snd_pcm_hw_param_set_integer(pcm, params, SND_TRY, SND_PCM_HW_PARAM_PERIOD_SIZE);
5528 }
5529 
5530 
5531 /**
5532  * \brief Extract periods from a configuration space
5533  * \param params Configuration space
5534  * \param val approximate periods per buffer
5535  * \param dir Sub unit direction
5536  * \return 0 otherwise a negative error code if the configuration space does not contain a single value
5537  *
5538  * Actual exact value is <,=,> the approximate one following dir (-1, 0, 1)
5539  */
5540 #ifndef DOXYGEN
snd_pcm_hw_params_get_periods(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)5541 EXPORT_SYMBOL int INTERNAL(snd_pcm_hw_params_get_periods)(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
5542 #else
5543 int snd_pcm_hw_params_get_periods(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
5544 #endif
5545 {
5546 	return snd_pcm_hw_param_get(params, SND_PCM_HW_PARAM_PERIODS, val, dir);
5547 }
5548 
5549 /**
5550  * \brief Extract minimum periods count from a configuration space
5551  * \param params Configuration space
5552  * \param val approximate minimum periods per buffer
5553  * \param dir Sub unit direction
5554  * \return 0 otherwise a negative error code
5555  *
5556  * Exact value is <,=,> the returned one following dir (-1,0,1)
5557  */
5558 #ifndef DOXYGEN
snd_pcm_hw_params_get_periods_min(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)5559 EXPORT_SYMBOL int INTERNAL(snd_pcm_hw_params_get_periods_min)(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
5560 #else
5561 int snd_pcm_hw_params_get_periods_min(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
5562 #endif
5563 {
5564 	return snd_pcm_hw_param_get_min(params, SND_PCM_HW_PARAM_PERIODS, val, dir);
5565 }
5566 
5567 /**
5568  * \brief Extract maximum periods count from a configuration space
5569  * \param params Configuration space
5570  * \param val approximate maximum periods per buffer
5571  * \param dir Sub unit direction
5572  * \return 0 otherwise a negative error code
5573  *
5574  * Exact value is <,=,> the returned one following dir (-1,0,1)
5575  */
5576 #ifndef DOXYGEN
snd_pcm_hw_params_get_periods_max(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)5577 EXPORT_SYMBOL int INTERNAL(snd_pcm_hw_params_get_periods_max)(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
5578 #else
5579 int snd_pcm_hw_params_get_periods_max(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
5580 #endif
5581 {
5582 	return snd_pcm_hw_param_get_max(params, SND_PCM_HW_PARAM_PERIODS, val, dir);
5583 }
5584 
5585 /**
5586  * \brief Verify if a periods count is available inside a configuration space for a PCM
5587  * \param pcm PCM handle
5588  * \param params Configuration space
5589  * \param val approximate periods per buffer
5590  * \param dir Sub unit direction
5591  * \return 0 if available a negative error code otherwise
5592  *
5593  * Wanted exact value is <,=,> val following dir (-1,0,1)
5594  */
snd_pcm_hw_params_test_periods(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir)5595 int snd_pcm_hw_params_test_periods(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir)
5596 {
5597 	return snd_pcm_hw_param_set(pcm, params, SND_TEST, SND_PCM_HW_PARAM_PERIODS, val, dir);
5598 }
5599 
5600 /**
5601  * \brief Restrict a configuration space to contain only one periods count
5602  * \param pcm PCM handle
5603  * \param params Configuration space
5604  * \param val approximate periods per buffer
5605  * \param dir Sub unit direction
5606  * \return 0 otherwise a negative error code if configuration space would become empty
5607  *
5608  * Wanted exact value is <,=,> val following dir (-1,0,1)
5609  */
snd_pcm_hw_params_set_periods(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir)5610 int snd_pcm_hw_params_set_periods(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir)
5611 {
5612 	return snd_pcm_hw_param_set(pcm, params, SND_TRY, SND_PCM_HW_PARAM_PERIODS, val, dir);
5613 }
5614 
5615 /**
5616  * \brief Restrict a configuration space with a minimum periods count
5617  * \param pcm PCM handle
5618  * \param params Configuration space
5619  * \param val approximate minimum periods per buffer (on return filled with actual minimum)
5620  * \param dir Sub unit direction (on return filled with actual direction)
5621  * \return 0 otherwise a negative error code if configuration space would become empty
5622  *
5623  * Wanted/actual exact minimum is <,=,> val following dir (-1,0,1)
5624  */
snd_pcm_hw_params_set_periods_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)5625 int snd_pcm_hw_params_set_periods_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
5626 {
5627 	return snd_pcm_hw_param_set_min(pcm, params, SND_TRY, SND_PCM_HW_PARAM_PERIODS, val, dir);
5628 }
5629 
5630 /**
5631  * \brief Restrict a configuration space with a maximum periods count
5632  * \param pcm PCM handle
5633  * \param params Configuration space
5634  * \param val approximate maximum periods per buffer (on return filled with actual maximum)
5635  * \param dir Sub unit direction (on return filled with actual direction)
5636  * \return 0 otherwise a negative error code if configuration space would become empty
5637  *
5638  * Wanted/actual exact maximum is <,=,> val following dir (-1,0,1)
5639  */
snd_pcm_hw_params_set_periods_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)5640 int snd_pcm_hw_params_set_periods_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
5641 {
5642 	return snd_pcm_hw_param_set_max(pcm, params, SND_TRY, SND_PCM_HW_PARAM_PERIODS, val, dir);
5643 }
5644 
5645 /**
5646  * \brief Restrict a configuration space to have periods counts in a given range
5647  * \param pcm PCM handle
5648  * \param params Configuration space
5649  * \param min approximate minimum periods per buffer (on return filled with actual minimum)
5650  * \param mindir Sub unit direction for minimum (on return filled with actual direction)
5651  * \param max approximate maximum periods per buffer (on return filled with actual maximum)
5652  * \param maxdir Sub unit direction for maximum (on return filled with actual direction)
5653  * \return 0 otherwise a negative error code if configuration space would become empty
5654  *
5655  * Wanted/actual exact min/max is <,=,> val following dir (-1,0,1)
5656  */
snd_pcm_hw_params_set_periods_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *min, int *mindir, unsigned int *max, int *maxdir)5657 int snd_pcm_hw_params_set_periods_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *min, int *mindir, unsigned int *max, int *maxdir)
5658 {
5659 	return snd_pcm_hw_param_set_minmax(pcm, params, SND_TRY, SND_PCM_HW_PARAM_PERIODS, min, mindir, max, maxdir);
5660 }
5661 
5662 /**
5663  * \brief Restrict a configuration space to have periods count nearest to a target
5664  * \param pcm PCM handle
5665  * \param params Configuration space
5666  * \param val approximate target periods per buffer / returned chosen approximate target periods per buffer
5667  * \param dir Sub unit direction
5668  * \return 0 otherwise a negative error code if configuration space is empty
5669  *
5670  * target/chosen exact value is <,=,> val following dir (-1,0,1)
5671  */
5672 #ifndef DOXYGEN
snd_pcm_hw_params_set_periods_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)5673 EXPORT_SYMBOL int INTERNAL(snd_pcm_hw_params_set_periods_near)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
5674 #else
5675 int snd_pcm_hw_params_set_periods_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
5676 #endif
5677 {
5678 	return snd_pcm_hw_param_set_near(pcm, params, SND_PCM_HW_PARAM_PERIODS, val, dir);
5679 }
5680 
5681 /**
5682  * \brief Restrict a configuration space to contain only its minimum periods count
5683  * \param pcm PCM handle
5684  * \param params Configuration space
5685  * \param val Returned approximate minimum periods per buffer
5686  * \param dir Sub unit direction
5687  * \return 0 otherwise a negative error code
5688  *
5689  * Actual exact value is <,=,> the approximate one following dir (-1, 0, 1)
5690  */
5691 #ifndef DOXYGEN
snd_pcm_hw_params_set_periods_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)5692 EXPORT_SYMBOL int INTERNAL(snd_pcm_hw_params_set_periods_first)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
5693 #else
5694 int snd_pcm_hw_params_set_periods_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
5695 #endif
5696 {
5697 	return snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_PERIODS, val, dir);
5698 }
5699 
5700 /**
5701  * \brief Restrict a configuration space to contain only its maximum periods count
5702  * \param pcm PCM handle
5703  * \param params Configuration space
5704  * \param val Returned approximate maximum periods per buffer
5705  * \param dir Sub unit direction
5706  * \return 0 otherwise a negative error code
5707  *
5708  * Actual exact value is <,=,> the approximate one following dir (-1, 0, 1)
5709  */
5710 #ifndef DOXYGEN
snd_pcm_hw_params_set_periods_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)5711 EXPORT_SYMBOL int INTERNAL(snd_pcm_hw_params_set_periods_last)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
5712 #else
5713 int snd_pcm_hw_params_set_periods_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
5714 #endif
5715 {
5716 	return snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_PERIODS, val, dir);
5717 }
5718 
5719 /**
5720  * \brief Restrict a configuration space to contain only integer periods counts
5721  * \param pcm PCM handle
5722  * \param params Configuration space
5723  * \return 0 otherwise a negative error code if configuration space would become empty
5724  */
snd_pcm_hw_params_set_periods_integer(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)5725 int snd_pcm_hw_params_set_periods_integer(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
5726 {
5727 	return snd_pcm_hw_param_set_integer(pcm, params, SND_TRY, SND_PCM_HW_PARAM_PERIODS);
5728 }
5729 
5730 
5731 /**
5732  * \brief Extract buffer time from a configuration space
5733  * \param params Configuration space
5734  * \param val Returned buffer time in us
5735  * \param dir Sub unit direction
5736  * \return 0 otherwise a negative error code if the configuration space does not contain a single value
5737  *
5738  * Actual exact value is <,=,> the approximate one following dir (-1, 0, 1)
5739  */
5740 #ifndef DOXYGEN
snd_pcm_hw_params_get_buffer_time(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)5741 EXPORT_SYMBOL int INTERNAL(snd_pcm_hw_params_get_buffer_time)(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
5742 #else
5743 int snd_pcm_hw_params_get_buffer_time(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
5744 #endif
5745 {
5746 	return snd_pcm_hw_param_get(params, SND_PCM_HW_PARAM_BUFFER_TIME, val, dir);
5747 }
5748 
5749 /**
5750  * \brief Extract minimum buffer time from a configuration space
5751  * \param params Configuration space
5752  * \param val approximate minimum buffer duration in us
5753  * \param dir Sub unit direction
5754  * \return 0 otherwise a negative error code
5755  *
5756  * Exact value is <,=,> the returned one following dir (-1,0,1)
5757  */
5758 #ifndef DOXYGEN
snd_pcm_hw_params_get_buffer_time_min(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)5759 EXPORT_SYMBOL int INTERNAL(snd_pcm_hw_params_get_buffer_time_min)(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
5760 #else
5761 int snd_pcm_hw_params_get_buffer_time_min(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
5762 #endif
5763 {
5764 	return snd_pcm_hw_param_get_min(params, SND_PCM_HW_PARAM_BUFFER_TIME, val, dir);
5765 }
5766 
5767 /**
5768  * \brief Extract maximum buffer time from a configuration space
5769  * \param params Configuration space
5770  * \param val approximate maximum buffer duration in us
5771  * \param dir Sub unit direction
5772  * \return 0 otherwise a negative error code
5773  *
5774  * Exact value is <,=,> the returned one following dir (-1,0,1)
5775  */
5776 #ifndef DOXYGEN
snd_pcm_hw_params_get_buffer_time_max(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)5777 EXPORT_SYMBOL int INTERNAL(snd_pcm_hw_params_get_buffer_time_max)(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
5778 #else
5779 int snd_pcm_hw_params_get_buffer_time_max(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
5780 #endif
5781 {
5782 	return snd_pcm_hw_param_get_max(params, SND_PCM_HW_PARAM_BUFFER_TIME, val, dir);
5783 }
5784 
5785 /**
5786  * \brief Verify if a buffer time is available inside a configuration space for a PCM
5787  * \param pcm PCM handle
5788  * \param params Configuration space
5789  * \param val approximate buffer duration in us
5790  * \param dir Sub unit direction
5791  * \return 0 if available a negative error code otherwise
5792  *
5793  * Wanted exact value is <,=,> val following dir (-1,0,1)
5794  */
snd_pcm_hw_params_test_buffer_time(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir)5795 int snd_pcm_hw_params_test_buffer_time(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir)
5796 {
5797 	return snd_pcm_hw_param_set(pcm, params, SND_TEST, SND_PCM_HW_PARAM_BUFFER_TIME, val, dir);
5798 }
5799 
5800 /**
5801  * \brief Restrict a configuration space to contain only one buffer time
5802  * \param pcm PCM handle
5803  * \param params Configuration space
5804  * \param val approximate buffer duration in us
5805  * \param dir Sub unit direction
5806  * \return 0 otherwise a negative error code if configuration space would become empty
5807  *
5808  * Wanted exact value is <,=,> val following dir (-1,0,1)
5809  */
snd_pcm_hw_params_set_buffer_time(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir)5810 int snd_pcm_hw_params_set_buffer_time(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir)
5811 {
5812 	return snd_pcm_hw_param_set(pcm, params, SND_TRY, SND_PCM_HW_PARAM_BUFFER_TIME, val, dir);
5813 }
5814 
5815 /**
5816  * \brief Restrict a configuration space with a minimum buffer time
5817  * \param pcm PCM handle
5818  * \param params Configuration space
5819  * \param val approximate minimum buffer duration in us (on return filled with actual minimum)
5820  * \param dir Sub unit direction (on return filled with actual direction)
5821  * \return 0 otherwise a negative error code if configuration space would become empty
5822  *
5823  * Wanted/actual exact minimum is <,=,> val following dir (-1,0,1)
5824  */
snd_pcm_hw_params_set_buffer_time_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)5825 int snd_pcm_hw_params_set_buffer_time_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
5826 {
5827 	return snd_pcm_hw_param_set_min(pcm, params, SND_TRY, SND_PCM_HW_PARAM_BUFFER_TIME, val, dir);
5828 }
5829 
5830 /**
5831  * \brief Restrict a configuration space with a maximum buffer time
5832  * \param pcm PCM handle
5833  * \param params Configuration space
5834  * \param val approximate maximum buffer duration in us (on return filled with actual maximum)
5835  * \param dir Sub unit direction (on return filled with actual direction)
5836  * \return 0 otherwise a negative error code if configuration space would become empty
5837  *
5838  * Wanted/actual exact maximum is <,=,> val following dir (-1,0,1)
5839  */
snd_pcm_hw_params_set_buffer_time_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)5840 int snd_pcm_hw_params_set_buffer_time_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
5841 {
5842 	return snd_pcm_hw_param_set_max(pcm, params, SND_TRY, SND_PCM_HW_PARAM_BUFFER_TIME, val, dir);
5843 }
5844 
5845 /**
5846  * \brief Restrict a configuration space to have buffer times in a given range
5847  * \param pcm PCM handle
5848  * \param params Configuration space
5849  * \param min approximate minimum buffer duration in us (on return filled with actual minimum)
5850  * \param mindir Sub unit direction for minimum (on return filled with actual direction)
5851  * \param max approximate maximum buffer duration in us (on return filled with actual maximum)
5852  * \param maxdir Sub unit direction for maximum (on return filled with actual direction)
5853  * \return 0 otherwise a negative error code if configuration space would become empty
5854  *
5855  * Wanted/actual exact min/max is <,=,> val following dir (-1,0,1)
5856  */
snd_pcm_hw_params_set_buffer_time_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *min, int *mindir, unsigned int *max, int *maxdir)5857 int snd_pcm_hw_params_set_buffer_time_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *min, int *mindir, unsigned int *max, int *maxdir)
5858 {
5859 	return snd_pcm_hw_param_set_minmax(pcm, params, SND_TRY, SND_PCM_HW_PARAM_BUFFER_TIME, min, mindir, max, maxdir);
5860 }
5861 
5862 /**
5863  * \brief Restrict a configuration space to have buffer time nearest to a target
5864  * \param pcm PCM handle
5865  * \param params Configuration space
5866  * \param val approximate target buffer duration in us / returned chosen approximate target buffer duration
5867  * \param dir Sub unit direction
5868  * \return 0 otherwise a negative error code if configuration space is empty
5869  *
5870  * target/chosen exact value is <,=,> val following dir (-1,0,1)
5871  */
5872 #ifndef DOXYGEN
snd_pcm_hw_params_set_buffer_time_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)5873 EXPORT_SYMBOL int INTERNAL(snd_pcm_hw_params_set_buffer_time_near)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
5874 #else
5875 int snd_pcm_hw_params_set_buffer_time_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
5876 #endif
5877 {
5878 	return snd_pcm_hw_param_set_near(pcm, params, SND_PCM_HW_PARAM_BUFFER_TIME, val, dir);
5879 }
5880 
5881 /**
5882  * \brief Restrict a configuration space to contain only its minimum buffer time
5883  * \param pcm PCM handle
5884  * \param params Configuration space
5885  * \param val Returned approximate minimum buffer duration in us
5886  * \param dir Sub unit direction
5887  * \return 0 otherwise a negative error code
5888  *
5889  * Actual exact value is <,=,> the approximate one following dir (-1, 0, 1)
5890  */
5891 #ifndef DOXYGEN
snd_pcm_hw_params_set_buffer_time_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)5892 EXPORT_SYMBOL int INTERNAL(snd_pcm_hw_params_set_buffer_time_first)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
5893 #else
5894 int snd_pcm_hw_params_set_buffer_time_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
5895 #endif
5896 {
5897 	return snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_BUFFER_TIME, val, dir);
5898 }
5899 
5900 /**
5901  * \brief Restrict a configuration space to contain only its maximum buffered time
5902  * \param pcm PCM handle
5903  * \param params Configuration space
5904  * \param val Returned approximate maximum buffer duration in us
5905  * \param dir Sub unit direction
5906  * \return 0 otherwise a negative error code
5907  *
5908  * Actual exact value is <,=,> the approximate one following dir (-1, 0, 1)
5909  */
5910 #ifndef DOXYGEN
snd_pcm_hw_params_set_buffer_time_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)5911 EXPORT_SYMBOL int INTERNAL(snd_pcm_hw_params_set_buffer_time_last)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
5912 #else
5913 int snd_pcm_hw_params_set_buffer_time_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
5914 #endif
5915 {
5916 	return snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_BUFFER_TIME, val, dir);
5917 }
5918 
5919 
5920 /**
5921  * \brief Extract buffer size from a configuration space
5922  * \param params Configuration space
5923  * \param val Returned buffer size in frames
5924  * \return 0 otherwise a negative error code if the configuration space does not contain a single value
5925  */
5926 #ifndef DOXYGEN
snd_pcm_hw_params_get_buffer_size(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val)5927 EXPORT_SYMBOL int INTERNAL(snd_pcm_hw_params_get_buffer_size)(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val)
5928 #else
5929 int snd_pcm_hw_params_get_buffer_size(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val)
5930 #endif
5931 {
5932 	unsigned int _val;
5933 	int err = snd_pcm_hw_param_get(params, SND_PCM_HW_PARAM_BUFFER_SIZE, &_val, NULL);
5934 	if (err >= 0)
5935 		*val = _val;
5936 	return err;
5937 }
5938 
5939 /**
5940  * \brief Extract minimum buffer size from a configuration space
5941  * \param params Configuration space
5942  * \param val Returned approximate minimum buffer size in frames
5943  * \return 0 otherwise a negative error code
5944  */
5945 #ifndef DOXYGEN
snd_pcm_hw_params_get_buffer_size_min(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val)5946 EXPORT_SYMBOL int INTERNAL(snd_pcm_hw_params_get_buffer_size_min)(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val)
5947 #else
5948 int snd_pcm_hw_params_get_buffer_size_min(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val)
5949 #endif
5950 {
5951 	unsigned int _val;
5952 	int err = snd_pcm_hw_param_get_min(params, SND_PCM_HW_PARAM_BUFFER_SIZE, &_val, NULL);
5953 	if (err >= 0)
5954 		*val = _val;
5955 	return err;
5956 }
5957 
5958 /**
5959  * \brief Extract maximum buffer size from a configuration space
5960  * \param params Configuration space
5961  * \param val Returned approximate maximum buffer size in frames
5962  * \return 0 otherwise a negative error code
5963  *
5964  * Exact value is <,=,> the returned one following dir (-1,0,1)
5965  */
5966 #ifndef DOXYGEN
snd_pcm_hw_params_get_buffer_size_max(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val)5967 EXPORT_SYMBOL int INTERNAL(snd_pcm_hw_params_get_buffer_size_max)(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val)
5968 #else
5969 int snd_pcm_hw_params_get_buffer_size_max(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val)
5970 #endif
5971 {
5972 	unsigned int _val;
5973 	int err = snd_pcm_hw_param_get_max(params, SND_PCM_HW_PARAM_BUFFER_SIZE, &_val, NULL);
5974 	if (err >= 0)
5975 		*val = _val;
5976 	return err;
5977 }
5978 
5979 /**
5980  * \brief Verify if a buffer size is available inside a configuration space for a PCM
5981  * \param pcm PCM handle
5982  * \param params Configuration space
5983  * \param val buffer size in frames
5984  * \return 0 if available a negative error code otherwise
5985  *
5986  * Wanted exact value is <,=,> val following dir (-1,0,1)
5987  */
snd_pcm_hw_params_test_buffer_size(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val)5988 int snd_pcm_hw_params_test_buffer_size(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val)
5989 {
5990 	return snd_pcm_hw_param_set(pcm, params, SND_TEST, SND_PCM_HW_PARAM_BUFFER_SIZE, val, 0);
5991 }
5992 
5993 /**
5994  * \brief Restrict a configuration space to contain only one buffer size
5995  * \param pcm PCM handle
5996  * \param params Configuration space
5997  * \param val buffer size in frames
5998  * \return 0 otherwise a negative error code if configuration space would become empty
5999  *
6000  * Wanted exact value is <,=,> val following dir (-1,0,1)
6001  */
snd_pcm_hw_params_set_buffer_size(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val)6002 int snd_pcm_hw_params_set_buffer_size(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val)
6003 {
6004 	return snd_pcm_hw_param_set(pcm, params, SND_TRY, SND_PCM_HW_PARAM_BUFFER_SIZE, val, 0);
6005 }
6006 
6007 /**
6008  * \brief Restrict a configuration space with a minimum buffer size
6009  * \param pcm PCM handle
6010  * \param params Configuration space
6011  * \param val approximate minimum buffer size in frames (on return filled with actual minimum)
6012  * \return 0 otherwise a negative error code if configuration space would become empty
6013  */
snd_pcm_hw_params_set_buffer_size_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val)6014 int snd_pcm_hw_params_set_buffer_size_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val)
6015 {
6016 	unsigned int _val = *val;
6017 	int err = snd_pcm_hw_param_set_min(pcm, params, SND_TRY, SND_PCM_HW_PARAM_BUFFER_SIZE, &_val, NULL);
6018 	if (err >= 0)
6019 		*val = _val;
6020 	return err;
6021 }
6022 
6023 /**
6024  * \brief Restrict a configuration space with a maximum buffer size
6025  * \param pcm PCM handle
6026  * \param params Configuration space
6027  * \param val approximate maximum buffer size in frames (on return filled with actual maximum)
6028  * \return 0 otherwise a negative error code if configuration space would become empty
6029  */
snd_pcm_hw_params_set_buffer_size_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val)6030 int snd_pcm_hw_params_set_buffer_size_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val)
6031 {
6032 	unsigned int _val = *val;
6033 	int err = snd_pcm_hw_param_set_max(pcm, params, SND_TRY, SND_PCM_HW_PARAM_BUFFER_SIZE, &_val, NULL);
6034 	if (err >= 0)
6035 		*val = _val;
6036 	return err;
6037 }
6038 
6039 /**
6040  * \brief Restrict a configuration space to have buffer sizes in a given range
6041  * \param pcm PCM handle
6042  * \param params Configuration space
6043  * \param min approximate minimum buffer size in frames (on return filled with actual minimum)
6044  * \param max approximate maximum buffer size in frames (on return filled with actual maximum)
6045  * \return 0 otherwise a negative error code if configuration space would become empty
6046  */
snd_pcm_hw_params_set_buffer_size_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *min, snd_pcm_uframes_t *max)6047 int snd_pcm_hw_params_set_buffer_size_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *min, snd_pcm_uframes_t *max)
6048 {
6049 	unsigned int _min = *min;
6050 	unsigned int _max = *max;
6051 	int err = snd_pcm_hw_param_set_minmax(pcm, params, SND_TRY, SND_PCM_HW_PARAM_BUFFER_SIZE, &_min, NULL, &_max, NULL);
6052 	*min = _min;
6053 	*max = _max;
6054 	return err;
6055 }
6056 
6057 /**
6058  * \brief Restrict a configuration space to have buffer size nearest to a target
6059  * \param pcm PCM handle
6060  * \param params Configuration space
6061  * \param val approximate target buffer size in frames / returned chosen approximate target buffer size in frames
6062  * \return 0 otherwise a negative error code if configuration space is empty
6063  */
6064 #ifndef DOXYGEN
snd_pcm_hw_params_set_buffer_size_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val)6065 EXPORT_SYMBOL int INTERNAL(snd_pcm_hw_params_set_buffer_size_near)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val)
6066 #else
6067 int snd_pcm_hw_params_set_buffer_size_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val)
6068 #endif
6069 {
6070 	unsigned int _val = *val;
6071 	int err = snd_pcm_hw_param_set_near(pcm, params, SND_PCM_HW_PARAM_BUFFER_SIZE, &_val, NULL);
6072 	if (err >= 0)
6073 		*val = _val;
6074 	return err;
6075 }
6076 
6077 /**
6078  * \brief Restrict a configuration space to contain only its minimum buffer size
6079  * \param pcm PCM handle
6080  * \param params Configuration space
6081  * \param val Returned minimum buffer size in frames
6082  * \return buffer size in frames
6083  */
6084 #ifndef DOXYGEN
snd_pcm_hw_params_set_buffer_size_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val)6085 EXPORT_SYMBOL int INTERNAL(snd_pcm_hw_params_set_buffer_size_first)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val)
6086 #else
6087 int snd_pcm_hw_params_set_buffer_size_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val)
6088 #endif
6089 {
6090 	unsigned int _val;
6091 	int err = snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_BUFFER_SIZE, &_val, NULL);
6092 	if (err >= 0)
6093 		*val = _val;
6094 	return err;
6095 }
6096 
6097 /**
6098  * \brief Restrict a configuration space to contain only its maximum buffer size
6099  * \param pcm PCM handle
6100  * \param params Configuration space
6101  * \param val Returned maximum buffer size in frames
6102  * \return 0 otherwise a negative error code
6103  */
6104 #ifndef DOXYGEN
snd_pcm_hw_params_set_buffer_size_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val)6105 EXPORT_SYMBOL int INTERNAL(snd_pcm_hw_params_set_buffer_size_last)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val)
6106 #else
6107 int snd_pcm_hw_params_set_buffer_size_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val)
6108 #endif
6109 {
6110 	unsigned int _val;
6111 	int err = snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_BUFFER_SIZE, &_val, NULL);
6112 	if (err >= 0)
6113 		*val = _val;
6114 	return err;
6115 }
6116 
6117 
6118 /**
6119  * \brief (DEPRECATED) Extract tick time from a configuration space
6120  * \param params Configuration space
6121  * \param val Returned approximate tick duration in us
6122  * \param dir Sub unit direction
6123  * \return 0 otherwise a negative error code if the configuration space does not contain a single value
6124  *
6125  * Actual exact value is <,=,> the approximate one following dir (-1, 0, 1)
6126  */
6127 #ifndef DOXYGEN
snd_pcm_hw_params_get_tick_time(const snd_pcm_hw_params_t *params ATTRIBUTE_UNUSED, unsigned int *val, int *dir ATTRIBUTE_UNUSED)6128 EXPORT_SYMBOL int INTERNAL(snd_pcm_hw_params_get_tick_time)(const snd_pcm_hw_params_t *params ATTRIBUTE_UNUSED, unsigned int *val, int *dir ATTRIBUTE_UNUSED)
6129 #else
6130 int snd_pcm_hw_params_get_tick_time(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
6131 #endif
6132 {
6133 	*val = 0;
6134 	return 0;
6135 }
6136 
6137 /**
6138  * \brief (DEPRECATED) Extract minimum tick time from a configuration space
6139  * \param params Configuration space
6140  * \param val Returned approximate minimum tick duration in us
6141  * \param dir Sub unit direction
6142  * \return 0 otherwise a negative error code
6143  *
6144  * Exact value is <,=,> the returned one following dir (-1,0,1)
6145  */
6146 #ifndef DOXYGEN
snd_pcm_hw_params_get_tick_time_min(const snd_pcm_hw_params_t *params ATTRIBUTE_UNUSED, unsigned int *val, int *dir ATTRIBUTE_UNUSED)6147 EXPORT_SYMBOL int INTERNAL(snd_pcm_hw_params_get_tick_time_min)(const snd_pcm_hw_params_t *params ATTRIBUTE_UNUSED, unsigned int *val, int *dir ATTRIBUTE_UNUSED)
6148 #else
6149 int snd_pcm_hw_params_get_tick_time_min(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
6150 #endif
6151 {
6152 	*val = 0;
6153 	return 0;
6154 }
6155 
6156 /**
6157  * \brief (DEPRECATED) Extract maximum tick time from a configuration space
6158  * \param params Configuration space
6159  * \param val Returned approximate maximum tick duration in us
6160  * \param dir Sub unit direction
6161  * \return 0 otherwise a negative error code
6162  *
6163  * Exact value is <,=,> the returned one following dir (-1,0,1)
6164  */
6165 #ifndef DOXYGEN
snd_pcm_hw_params_get_tick_time_max(const snd_pcm_hw_params_t *params ATTRIBUTE_UNUSED, unsigned int *val, int *dir ATTRIBUTE_UNUSED)6166 EXPORT_SYMBOL int INTERNAL(snd_pcm_hw_params_get_tick_time_max)(const snd_pcm_hw_params_t *params ATTRIBUTE_UNUSED, unsigned int *val, int *dir ATTRIBUTE_UNUSED)
6167 #else
6168 int snd_pcm_hw_params_get_tick_time_max(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
6169 #endif
6170 {
6171 	*val = 0;
6172 	return 0;
6173 }
6174 
6175 /**
6176  * \brief (DEPRECATED) Verify if a tick time is available inside a configuration space for a PCM
6177  * \param pcm PCM handle
6178  * \param params Configuration space
6179  * \param val approximate tick duration in us
6180  * \param dir Sub unit direction
6181  * \return 0 if available a negative error code otherwise
6182  *
6183  * Wanted exact value is <,=,> val following dir (-1,0,1)
6184  */
snd_pcm_hw_params_test_tick_time(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_hw_params_t *params ATTRIBUTE_UNUSED, unsigned int val, int dir ATTRIBUTE_UNUSED)6185 int snd_pcm_hw_params_test_tick_time(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_hw_params_t *params ATTRIBUTE_UNUSED, unsigned int val, int dir ATTRIBUTE_UNUSED)
6186 {
6187 	return val ? -EINVAL : 0;
6188 }
6189 
6190 /**
6191  * \brief (DEPRECATED) Restrict a configuration space to contain only one tick time
6192  * \param pcm PCM handle
6193  * \param params Configuration space
6194  * \param val approximate tick duration in us
6195  * \param dir Sub unit direction
6196  * \return 0 otherwise a negative error code if configuration space would become empty
6197  *
6198  * Wanted exact value is <,=,> val following dir (-1,0,1)
6199  */
snd_pcm_hw_params_set_tick_time(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_hw_params_t *params ATTRIBUTE_UNUSED, unsigned int val ATTRIBUTE_UNUSED, int dir ATTRIBUTE_UNUSED)6200 int snd_pcm_hw_params_set_tick_time(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_hw_params_t *params ATTRIBUTE_UNUSED, unsigned int val ATTRIBUTE_UNUSED, int dir ATTRIBUTE_UNUSED)
6201 {
6202 	return 0;
6203 }
6204 
6205 /**
6206  * \brief (DEPRECATED) Restrict a configuration space with a minimum tick time
6207  * \param pcm PCM handle
6208  * \param params Configuration space
6209  * \param val approximate minimum tick duration in us (on return filled with actual minimum)
6210  * \param dir Sub unit direction (on return filled with actual direction)
6211  * \return 0 otherwise a negative error code if configuration space would become empty
6212  *
6213  * Wanted/actual exact minimum is <,=,> val following dir (-1,0,1)
6214  */
snd_pcm_hw_params_set_tick_time_min(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_hw_params_t *params ATTRIBUTE_UNUSED, unsigned int *val ATTRIBUTE_UNUSED, int *dir ATTRIBUTE_UNUSED)6215 int snd_pcm_hw_params_set_tick_time_min(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_hw_params_t *params ATTRIBUTE_UNUSED, unsigned int *val ATTRIBUTE_UNUSED, int *dir ATTRIBUTE_UNUSED)
6216 {
6217 	return 0;
6218 }
6219 
6220 /**
6221  * \brief (DEPRECATED) Restrict a configuration space with a maximum tick time
6222  * \param pcm PCM handle
6223  * \param params Configuration space
6224  * \param val approximate maximum tick duration in us (on return filled with actual maximum)
6225  * \param dir Sub unit direction (on return filled with actual direction)
6226  * \return 0 otherwise a negative error code if configuration space would become empty
6227  *
6228  * Wanted/actual exact maximum is <,=,> val following dir (-1,0,1)
6229  */
snd_pcm_hw_params_set_tick_time_max(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_hw_params_t *params ATTRIBUTE_UNUSED, unsigned int *val ATTRIBUTE_UNUSED, int *dir ATTRIBUTE_UNUSED)6230 int snd_pcm_hw_params_set_tick_time_max(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_hw_params_t *params ATTRIBUTE_UNUSED, unsigned int *val ATTRIBUTE_UNUSED, int *dir ATTRIBUTE_UNUSED)
6231 {
6232 	return 0;
6233 }
6234 
6235 /**
6236  * \brief (DEPRECATED) Restrict a configuration space to have tick times in a given range
6237  * \param pcm PCM handle
6238  * \param params Configuration space
6239  * \param min approximate minimum tick duration in us (on return filled with actual minimum)
6240  * \param mindir Sub unit direction for minimum (on return filled with actual direction)
6241  * \param max approximate maximum tick duration in us (on return filled with actual maximum)
6242  * \param maxdir Sub unit direction for maximum (on return filled with actual direction)
6243  * \return 0 otherwise a negative error code if configuration space would become empty
6244  *
6245  * Wanted/actual exact min/max is <,=,> val following dir (-1,0,1)
6246  */
snd_pcm_hw_params_set_tick_time_minmax(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_hw_params_t *params ATTRIBUTE_UNUSED, unsigned int *min ATTRIBUTE_UNUSED, int *mindir ATTRIBUTE_UNUSED, unsigned int *max ATTRIBUTE_UNUSED, int *maxdir ATTRIBUTE_UNUSED)6247 int snd_pcm_hw_params_set_tick_time_minmax(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_hw_params_t *params ATTRIBUTE_UNUSED, unsigned int *min ATTRIBUTE_UNUSED, int *mindir ATTRIBUTE_UNUSED, unsigned int *max ATTRIBUTE_UNUSED, int *maxdir ATTRIBUTE_UNUSED)
6248 {
6249 	return 0;
6250 }
6251 
6252 /**
6253  * \brief (DEPRECATED) Restrict a configuration space to have tick time nearest to a target
6254  * \param pcm PCM handle
6255  * \param params Configuration space
6256  * \param val approximate target tick duration in us / returned chosen approximate target tick duration in us
6257  * \param dir Sub unit direction
6258  * \return 0 otherwise a negative error code if configuration space is empty
6259  *
6260  * target/chosen exact value is <,=,> val following dir (-1,0,1)
6261  */
6262 #ifndef DOXYGEN
snd_pcm_hw_params_set_tick_time_near(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_hw_params_t *params ATTRIBUTE_UNUSED, unsigned int *val ATTRIBUTE_UNUSED, int *dir ATTRIBUTE_UNUSED)6263 EXPORT_SYMBOL int INTERNAL(snd_pcm_hw_params_set_tick_time_near)(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_hw_params_t *params ATTRIBUTE_UNUSED, unsigned int *val ATTRIBUTE_UNUSED, int *dir ATTRIBUTE_UNUSED)
6264 #else
6265 int snd_pcm_hw_params_set_tick_time_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
6266 #endif
6267 {
6268 	return 0;
6269 }
6270 
6271 /**
6272  * \brief (DEPRECATED) Restrict a configuration space to contain only its minimum tick time
6273  * \param pcm PCM handle
6274  * \param params Configuration space
6275  * \param val Returned approximate minimum tick duration in us
6276  * \param dir Sub unit direction
6277  * \return 0 otherwise a negative error code
6278  *
6279  * Actual exact value is <,=,> the approximate one following dir (-1, 0, 1)
6280  */
6281 #ifndef DOXYGEN
snd_pcm_hw_params_set_tick_time_first(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_hw_params_t *params ATTRIBUTE_UNUSED, unsigned int *val ATTRIBUTE_UNUSED, int *dir ATTRIBUTE_UNUSED)6282 EXPORT_SYMBOL int INTERNAL(snd_pcm_hw_params_set_tick_time_first)(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_hw_params_t *params ATTRIBUTE_UNUSED, unsigned int *val ATTRIBUTE_UNUSED, int *dir ATTRIBUTE_UNUSED)
6283 #else
6284 int snd_pcm_hw_params_set_tick_time_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
6285 #endif
6286 {
6287 	return 0;
6288 }
6289 
6290 /**
6291  * \brief (DEPRECATED) Restrict a configuration space to contain only its maximum tick time
6292  * \param pcm PCM handle
6293  * \param params Configuration space
6294  * \param val Returned approximate maximum tick duration in us
6295  * \param dir Sub unit direction
6296  * \return 0 otherwise a negative error code
6297  *
6298  * Actual exact value is <,=,> the approximate one following dir (-1, 0, 1)
6299  */
6300 #ifndef DOXYGEN
snd_pcm_hw_params_set_tick_time_last(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_hw_params_t *params ATTRIBUTE_UNUSED, unsigned int *val ATTRIBUTE_UNUSED, int *dir ATTRIBUTE_UNUSED)6301 EXPORT_SYMBOL int INTERNAL(snd_pcm_hw_params_set_tick_time_last)(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_hw_params_t *params ATTRIBUTE_UNUSED, unsigned int *val ATTRIBUTE_UNUSED, int *dir ATTRIBUTE_UNUSED)
6302 #else
6303 int snd_pcm_hw_params_set_tick_time_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
6304 #endif
6305 {
6306 	return 0;
6307 }
6308 
6309 /**
6310  * \brief Get the minimum transfer align value in samples
6311  * \param params Configuration space
6312  * \param val Returned minimum align value
6313  * \return 0 otherwise a negative error code if the configuration space does not contain a single value
6314  */
snd_pcm_hw_params_get_min_align(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val)6315 int snd_pcm_hw_params_get_min_align(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val)
6316 {
6317 	unsigned int format, channels, fb, min_align;
6318 	int err;
6319 
6320 	err = snd_pcm_hw_param_get(params, SND_PCM_HW_PARAM_FORMAT, &format, NULL);
6321 	if (err < 0)
6322 		return err;
6323 	err = snd_pcm_hw_param_get(params, SND_PCM_HW_PARAM_CHANNELS, &channels, NULL);
6324 	if (err < 0)
6325 		return err;
6326 	// compute frame bits
6327 	fb = snd_pcm_format_physical_width((snd_pcm_format_t)format) * channels;
6328         min_align = 1;
6329 	while (fb % 8) {
6330 		fb *= 2;
6331                 min_align *= 2;
6332 	}
6333 	if (val)
6334 		*val = min_align;
6335 	return 0;
6336 }
6337 
6338 #ifndef DOXYGEN
snd_pcm_sw_params_current_no_lock(snd_pcm_t *pcm, snd_pcm_sw_params_t *params)6339 void snd_pcm_sw_params_current_no_lock(snd_pcm_t *pcm, snd_pcm_sw_params_t *params)
6340 {
6341 	params->proto = SNDRV_PCM_VERSION;
6342 	params->tstamp_mode = pcm->tstamp_mode;
6343 	params->tstamp_type = pcm->tstamp_type;
6344 	params->period_step = pcm->period_step;
6345 	params->sleep_min = 0;
6346 	params->avail_min = pcm->avail_min;
6347 	sw_set_period_event(params, pcm->period_event);
6348 	params->xfer_align = 1;
6349 	params->start_threshold = pcm->start_threshold;
6350 	params->stop_threshold = pcm->stop_threshold;
6351 	params->silence_threshold = pcm->silence_threshold;
6352 	params->silence_size = pcm->silence_size;
6353 	params->boundary = pcm->boundary;
6354 }
6355 #endif
6356 
6357 /**
6358  * \brief Return current software configuration for a PCM
6359  * \param pcm PCM handle
6360  * \param params Software configuration container
6361  * \return 0 on success otherwise a negative error code
6362  *
6363  * The function is thread-safe when built with the proper option.
6364  */
snd_pcm_sw_params_current(snd_pcm_t *pcm, snd_pcm_sw_params_t *params)6365 int snd_pcm_sw_params_current(snd_pcm_t *pcm, snd_pcm_sw_params_t *params)
6366 {
6367 	assert(pcm && params);
6368 	if (CHECK_SANITY(! pcm->setup)) {
6369 		SNDMSG("PCM not set up");
6370 		return -EIO;
6371 	}
6372 	__snd_pcm_lock(pcm); /* forced lock due to pcm field changes */
6373 	snd_pcm_sw_params_current_no_lock(pcm, params);
6374 	__snd_pcm_unlock(pcm);
6375 	return 0;
6376 }
6377 
6378 /**
6379  * \brief Dump a software configuration
6380  * \param params Software configuration container
6381  * \param out Output handle
6382  * \return 0 on success otherwise a negative error code
6383  */
snd_pcm_sw_params_dump(snd_pcm_sw_params_t *params, snd_output_t *out)6384 int snd_pcm_sw_params_dump(snd_pcm_sw_params_t *params, snd_output_t *out)
6385 {
6386 	snd_output_printf(out, "tstamp_mode: %s\n", snd_pcm_tstamp_mode_name(params->tstamp_mode));
6387 	snd_output_printf(out, "tstamp_type: %s\n", snd_pcm_tstamp_type_name(params->tstamp_type));
6388 	snd_output_printf(out, "period_step: %u\n", params->period_step);
6389 	snd_output_printf(out, "avail_min: %lu\n", params->avail_min);
6390 	snd_output_printf(out, "start_threshold: %ld\n", params->start_threshold);
6391 	snd_output_printf(out, "stop_threshold: %ld\n", params->stop_threshold);
6392 	snd_output_printf(out, "silence_threshold: %lu\n", params->silence_threshold);
6393 	snd_output_printf(out, "silence_size: %lu\n", params->silence_size);
6394 	snd_output_printf(out, "boundary: %lu\n", params->boundary);
6395 	return 0;
6396 }
6397 
6398 /**
6399  * \brief get size of #snd_pcm_sw_params_t
6400  * \return size in bytes
6401  */
snd_pcm_sw_params_sizeofnull6402 size_t snd_pcm_sw_params_sizeof()
6403 {
6404 	return sizeof(snd_pcm_sw_params_t);
6405 }
6406 
6407 /**
6408  * \brief allocate an invalid #snd_pcm_sw_params_t using standard malloc
6409  * \param ptr returned pointer
6410  * \return 0 on success otherwise negative error code
6411  */
snd_pcm_sw_params_malloc(snd_pcm_sw_params_t **ptr)6412 int snd_pcm_sw_params_malloc(snd_pcm_sw_params_t **ptr)
6413 {
6414 	assert(ptr);
6415 	*ptr = calloc(1, sizeof(snd_pcm_sw_params_t));
6416 	if (!*ptr)
6417 		return -ENOMEM;
6418 	return 0;
6419 }
6420 
6421 /**
6422  * \brief frees a previously allocated #snd_pcm_sw_params_t
6423  * \param obj pointer to object to free
6424  */
snd_pcm_sw_params_free(snd_pcm_sw_params_t *obj)6425 void snd_pcm_sw_params_free(snd_pcm_sw_params_t *obj)
6426 {
6427 	free(obj);
6428 }
6429 
6430 /**
6431  * \brief copy one #snd_pcm_sw_params_t to another
6432  * \param dst pointer to destination
6433  * \param src pointer to source
6434  */
snd_pcm_sw_params_copy(snd_pcm_sw_params_t *dst, const snd_pcm_sw_params_t *src)6435 void snd_pcm_sw_params_copy(snd_pcm_sw_params_t *dst, const snd_pcm_sw_params_t *src)
6436 {
6437 	assert(dst && src);
6438 	*dst = *src;
6439 }
6440 
6441 /**
6442  * \brief Get boundary for ring pointers from a software configuration container
6443  * \param params Software configuration container
6444  * \param val Returned boundary in frames
6445  * \return 0 otherwise a negative error code
6446  */
snd_pcm_sw_params_get_boundary(const snd_pcm_sw_params_t *params, snd_pcm_uframes_t *val)6447 int snd_pcm_sw_params_get_boundary(const snd_pcm_sw_params_t *params, snd_pcm_uframes_t *val)
6448 {
6449 	assert(params);
6450 	*val = params->boundary;
6451 	return 0;
6452 }
6453 
6454 /**
6455  * \brief (DEPRECATED) Set start mode inside a software configuration container
6456  * \param pcm PCM handle
6457  * \param params Software configuration container
6458  * \param val Start mode
6459  * \return 0 otherwise a negative error code
6460  */
snd_pcm_sw_params_set_start_mode(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_start_t val)6461 int snd_pcm_sw_params_set_start_mode(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_start_t val)
6462 {
6463 	assert(pcm && params);
6464 	switch (val) {
6465 	case SND_PCM_START_DATA:
6466 		params->start_threshold = 1;
6467 		break;
6468 	case SND_PCM_START_EXPLICIT:
6469 		params->start_threshold = pcm->boundary;
6470 		break;
6471 	default:
6472 		SNDMSG("invalid start mode value %d", val);
6473 		return -EINVAL;
6474 	}
6475 	return 0;
6476 }
6477 
6478 #ifndef DOC_HIDDEN
6479 link_warning(snd_pcm_sw_params_set_start_mode, "Warning: start_mode is deprecated, consider to use start_threshold");
6480 #endif
6481 
6482 /**
6483  * \brief (DEPRECATED) Get start mode from a software configuration container
6484  * \param params Software configuration container
6485  * \return start mode
6486  */
snd_pcm_sw_params_get_start_mode(const snd_pcm_sw_params_t *params)6487 snd_pcm_start_t snd_pcm_sw_params_get_start_mode(const snd_pcm_sw_params_t *params)
6488 {
6489 	assert(params);
6490 	/* FIXME: Ugly */
6491 	return params->start_threshold > 1024 * 1024 ? SND_PCM_START_EXPLICIT : SND_PCM_START_DATA;
6492 }
6493 
6494 #ifndef DOC_HIDDEN
6495 link_warning(snd_pcm_sw_params_get_start_mode, "Warning: start_mode is deprecated, consider to use start_threshold");
6496 #endif
6497 
6498 /**
6499  * \brief (DEPRECATED) Set xrun mode inside a software configuration container
6500  * \param pcm PCM handle
6501  * \param params Software configuration container
6502  * \param val Xrun mode
6503  * \return 0 otherwise a negative error code
6504  */
6505 #ifndef DOXYGEN
snd_pcm_sw_params_set_xrun_mode(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_sw_params_t *params, snd_pcm_xrun_t val)6506 int snd_pcm_sw_params_set_xrun_mode(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_sw_params_t *params, snd_pcm_xrun_t val)
6507 #else
6508 int snd_pcm_sw_params_set_xrun_mode(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_xrun_t val)
6509 #endif
6510 {
6511 	assert(pcm && params);
6512 	switch (val) {
6513 	case SND_PCM_XRUN_STOP:
6514 		params->stop_threshold = pcm->buffer_size;
6515 		break;
6516 	case SND_PCM_XRUN_NONE:
6517 		params->stop_threshold = pcm->boundary;
6518 		break;
6519 	default:
6520 		SNDMSG("invalid xrun mode value %d", val);
6521 		return -EINVAL;
6522 	}
6523 	return 0;
6524 }
6525 
6526 #ifndef DOC_HIDDEN
6527 link_warning(snd_pcm_sw_params_set_xrun_mode, "Warning: xrun_mode is deprecated, consider to use stop_threshold");
6528 #endif
6529 
6530 /**
6531  * \brief (DEPRECATED) Get xrun mode from a software configuration container
6532  * \param params Software configuration container
6533  * \return xrun mode
6534  */
snd_pcm_sw_params_get_xrun_mode(const snd_pcm_sw_params_t *params)6535 snd_pcm_xrun_t snd_pcm_sw_params_get_xrun_mode(const snd_pcm_sw_params_t *params)
6536 {
6537 	assert(params);
6538 	/* FIXME: Ugly */
6539 	return params->stop_threshold > 1024 * 1024 ? SND_PCM_XRUN_NONE : SND_PCM_XRUN_STOP;
6540 }
6541 
6542 #ifndef DOC_HIDDEN
6543 link_warning(snd_pcm_sw_params_get_xrun_mode, "Warning: xrun_mode is deprecated, consider to use stop_threshold");
6544 #endif
6545 
6546 /**
6547  * \brief Set timestamp mode inside a software configuration container
6548  * \param pcm PCM handle
6549  * \param params Software configuration container
6550  * \param val Timestamp mode
6551  * \return 0 otherwise a negative error code
6552  */
6553 #ifndef DOXYGEN
snd_pcm_sw_params_set_tstamp_mode(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_sw_params_t *params, snd_pcm_tstamp_t val)6554 int snd_pcm_sw_params_set_tstamp_mode(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_sw_params_t *params, snd_pcm_tstamp_t val)
6555 #else
6556 int snd_pcm_sw_params_set_tstamp_mode(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_tstamp_t val)
6557 #endif
6558 {
6559 	assert(pcm && params);
6560 	if (CHECK_SANITY(val > SND_PCM_TSTAMP_LAST)) {
6561 		SNDMSG("invalid tstamp_mode value %d", val);
6562 		return -EINVAL;
6563 	}
6564 	params->tstamp_mode = val;
6565 	return 0;
6566 }
6567 
6568 /**
6569  * \brief Get timestamp mode from a software configuration container
6570  * \param params Software configuration container
6571  * \param val Returned timestamp
6572  * \return 0 otherwise a negative error code
6573  */
6574 #ifndef DOXYGEN
snd_pcm_sw_params_get_tstamp_mode(const snd_pcm_sw_params_t *params, snd_pcm_tstamp_t *val)6575 EXPORT_SYMBOL int INTERNAL(snd_pcm_sw_params_get_tstamp_mode)(const snd_pcm_sw_params_t *params, snd_pcm_tstamp_t *val)
6576 #else
6577 int snd_pcm_sw_params_get_tstamp_mode(const snd_pcm_sw_params_t *params, snd_pcm_tstamp_t *val)
6578 #endif
6579 {
6580 	assert(params && val);
6581 	*val = params->tstamp_mode;
6582 	return 0;
6583 }
6584 
6585 /**
6586  * \brief Set timestamp type inside a software configuration container
6587  * \param pcm PCM handle
6588  * \param params Software configuration container
6589  * \param val Timestamp type
6590  * \return 0 otherwise a negative error code
6591  */
snd_pcm_sw_params_set_tstamp_type(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_tstamp_type_t val)6592 int snd_pcm_sw_params_set_tstamp_type(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_tstamp_type_t val)
6593 {
6594 	assert(pcm && params);
6595 	if (CHECK_SANITY(val > SND_PCM_TSTAMP_TYPE_LAST)) {
6596 		SNDMSG("invalid tstamp_type value %d", val);
6597 		return -EINVAL;
6598 	}
6599 	params->tstamp_type = val;
6600 	return 0;
6601 }
6602 
6603 /**
6604  * \brief Get timestamp type from a software configuration container
6605  * \param params Software configuration container
6606  * \param val Returned timestamp type
6607  * \return 0 otherwise a negative error code
6608  */
snd_pcm_sw_params_get_tstamp_type(const snd_pcm_sw_params_t *params, snd_pcm_tstamp_type_t *val)6609 int snd_pcm_sw_params_get_tstamp_type(const snd_pcm_sw_params_t *params, snd_pcm_tstamp_type_t *val)
6610 {
6611 	assert(params && val);
6612 	*val = params->tstamp_type;
6613 	return 0;
6614 }
6615 
6616 /**
6617  * \brief (DEPRECATED) Set minimum number of ticks to sleep inside a software configuration container
6618  * \param pcm PCM handle
6619  * \param params Software configuration container
6620  * \param val Minimum ticks to sleep or 0 to disable the use of tick timer
6621  * \return 0 otherwise a negative error code
6622  */
6623 #ifndef DOXYGEN
snd_pcm_sw_params_set_sleep_min(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_sw_params_t *params ATTRIBUTE_UNUSED, unsigned int val ATTRIBUTE_UNUSED)6624 int snd_pcm_sw_params_set_sleep_min(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_sw_params_t *params ATTRIBUTE_UNUSED, unsigned int val ATTRIBUTE_UNUSED)
6625 #else
6626 int snd_pcm_sw_params_set_sleep_min(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, unsigned int val)
6627 #endif
6628 {
6629 	return 0;
6630 }
6631 
6632 /**
6633  * \brief (DEPRECATED) Get minimum numbers of ticks to sleep from a software configuration container
6634  * \param params Software configuration container
6635  * \param val returned minimum number of ticks to sleep or 0 if tick timer is disabled
6636  * \return 0 otherwise a negative error code
6637  */
6638 #ifndef DOXYGEN
snd_pcm_sw_params_get_sleep_min(const snd_pcm_sw_params_t *params ATTRIBUTE_UNUSED, unsigned int *val)6639 EXPORT_SYMBOL int INTERNAL(snd_pcm_sw_params_get_sleep_min)(const snd_pcm_sw_params_t *params ATTRIBUTE_UNUSED, unsigned int *val)
6640 #else
6641 int snd_pcm_sw_params_get_sleep_min(const snd_pcm_sw_params_t *params, unsigned int *val)
6642 #endif
6643 {
6644 	*val = 0;
6645 	return 0;
6646 }
6647 
6648 /**
6649  * \brief Set avail min inside a software configuration container
6650  * \param pcm PCM handle
6651  * \param params Software configuration container
6652  * \param val Minimum avail frames to consider PCM ready
6653  * \return 0 otherwise a negative error code
6654  *
6655  * Note: This is similar to setting an OSS wakeup point.  The valid
6656  * values for 'val' are determined by the specific hardware.  Most PC
6657  * sound cards can only accept power of 2 frame counts (i.e. 512,
6658  * 1024, 2048).  You cannot use this as a high resolution timer - it
6659  * is limited to how often the sound card hardware raises an
6660  * interrupt.
6661  */
6662 #ifndef DOXYGEN
snd_pcm_sw_params_set_avail_min(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val)6663 EXPORT_SYMBOL int snd_pcm_sw_params_set_avail_min(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val)
6664 #else
6665 int snd_pcm_sw_params_set_avail_min(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val)
6666 #endif
6667 {
6668 	assert(pcm && params);
6669 	/* Fix avail_min if it's below period size.  The period_size
6670 	 * defines the minimal wake-up timing accuracy, so it doesn't
6671 	 * make sense to set below that.
6672 	 */
6673 	if (val < pcm->period_size)
6674 		val = pcm->period_size;
6675 	params->avail_min = val;
6676 	return 0;
6677 }
6678 
6679 /**
6680  * \brief Get avail min from a software configuration container
6681  * \param params Software configuration container
6682  * \param val returned minimum available frames to consider PCM ready
6683  * \return 0 otherwise a negative error code
6684  *
6685  * This is a threshold value when the PCM stream is considered as ready for
6686  * another read/write operation or poll event.
6687  */
6688 #ifndef DOXYGEN
snd_pcm_sw_params_get_avail_min(const snd_pcm_sw_params_t *params, snd_pcm_uframes_t *val)6689 EXPORT_SYMBOL int INTERNAL(snd_pcm_sw_params_get_avail_min)(const snd_pcm_sw_params_t *params, snd_pcm_uframes_t *val)
6690 #else
6691 int snd_pcm_sw_params_get_avail_min(const snd_pcm_sw_params_t *params, snd_pcm_uframes_t *val)
6692 #endif
6693 {
6694 	assert(params && val);
6695 	*val = params->avail_min;
6696 	return 0;
6697 }
6698 
6699 /**
6700  * \brief Set period event inside a software configuration container
6701  * \param pcm PCM handle
6702  * \param params Software configuration container
6703  * \param val 0 = disable period event, 1 = enable period event
6704  * \return 0 otherwise a negative error code
6705  *
6706  * An poll (select) wakeup event is raised if enabled.
6707  */
snd_pcm_sw_params_set_period_event(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, int val)6708 int snd_pcm_sw_params_set_period_event(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, int val)
6709 {
6710 	assert(pcm && params);
6711 	sw_set_period_event(params, val);
6712 	return 0;
6713 }
6714 
6715 /**
6716  * \brief Get period event from a software configuration container
6717  * \param params Software configuration container
6718  * \param val returned period event state
6719  * \return 0 otherwise a negative error code
6720  */
snd_pcm_sw_params_get_period_event(const snd_pcm_sw_params_t *params, int *val)6721 int snd_pcm_sw_params_get_period_event(const snd_pcm_sw_params_t *params, int *val)
6722 {
6723 	assert(params && val);
6724 	*val = sw_get_period_event(params);
6725 	return 0;
6726 }
6727 
6728 /**
6729  * \brief (DEPRECATED) Set xfer align inside a software configuration container
6730  * \param pcm PCM handle
6731  * \param params Software configuration container
6732  * \param val Chunk size (frames are attempted to be transferred in chunks)
6733  * \return 0 otherwise a negative error code
6734  */
6735 #ifndef DOXYGEN
snd_pcm_sw_params_set_xfer_align(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_sw_params_t *params ATTRIBUTE_UNUSED, snd_pcm_uframes_t val ATTRIBUTE_UNUSED)6736 EXPORT_SYMBOL int snd_pcm_sw_params_set_xfer_align(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_sw_params_t *params ATTRIBUTE_UNUSED, snd_pcm_uframes_t val ATTRIBUTE_UNUSED)
6737 #else
6738 int snd_pcm_sw_params_set_xfer_align(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val)
6739 #endif
6740 {
6741 	return 0;
6742 }
6743 
6744 /**
6745  * \brief (DEPRECATED) Get xfer align from a software configuration container
6746  * \param params Software configuration container
6747  * \param val returned chunk size (frames are attempted to be transferred in chunks)
6748  * \return 0 otherwise a negative error code
6749  */
6750 #ifndef DOXYGEN
snd_pcm_sw_params_get_xfer_align(const snd_pcm_sw_params_t *params ATTRIBUTE_UNUSED, snd_pcm_uframes_t *val)6751 EXPORT_SYMBOL int INTERNAL(snd_pcm_sw_params_get_xfer_align)(const snd_pcm_sw_params_t *params ATTRIBUTE_UNUSED, snd_pcm_uframes_t *val)
6752 #else
6753 int snd_pcm_sw_params_get_xfer_align(const snd_pcm_sw_params_t *params, snd_pcm_uframes_t *val)
6754 #endif
6755 {
6756 	*val = 1;
6757 	return 0;
6758 }
6759 
6760 /**
6761  * \brief Set start threshold inside a software configuration container
6762  * \param pcm PCM handle
6763  * \param params Software configuration container
6764  * \param val Start threshold in frames
6765  * \return 0 otherwise a negative error code
6766  *
6767  * PCM is automatically started when playback frames available to PCM
6768  * are >= threshold or when requested capture frames are >= threshold
6769  */
6770 #ifndef DOXYGEN
snd_pcm_sw_params_set_start_threshold(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val)6771 EXPORT_SYMBOL int snd_pcm_sw_params_set_start_threshold(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val)
6772 #else
6773 int snd_pcm_sw_params_set_start_threshold(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val)
6774 #endif
6775 {
6776 	assert(pcm && params);
6777 	params->start_threshold = val;
6778 	return 0;
6779 }
6780 
6781 /**
6782  * \brief Get start threshold from a software configuration container
6783  * \param params Software configuration container
6784  * \param val Returned start threshold in frames
6785  * \return 0 otherwise a negative error code
6786  *
6787  * PCM is automatically started when playback frames available to PCM
6788  * are >= threshold or when requested capture frames are >= threshold
6789  */
6790 #ifndef DOXYGEN
snd_pcm_sw_params_get_start_threshold(const snd_pcm_sw_params_t *params, snd_pcm_uframes_t *val)6791 EXPORT_SYMBOL int INTERNAL(snd_pcm_sw_params_get_start_threshold)(const snd_pcm_sw_params_t *params, snd_pcm_uframes_t *val)
6792 #else
6793 int snd_pcm_sw_params_get_start_threshold(const snd_pcm_sw_params_t *params, snd_pcm_uframes_t *val)
6794 #endif
6795 {
6796 	assert(params);
6797 	*val = params->start_threshold;
6798 	return 0;
6799 }
6800 
6801 
6802 /**
6803  * \brief Set stop threshold inside a software configuration container
6804  * \param pcm PCM handle
6805  * \param params Software configuration container
6806  * \param val Stop threshold in frames
6807  * \return 0 otherwise a negative error code
6808  *
6809  * PCM is automatically stopped in #SND_PCM_STATE_XRUN state when available
6810  * frames is >= threshold. If the stop threshold is equal to boundary (also
6811  * software parameter - sw_param) then automatic stop will be disabled
6812  * (thus device will do the endless loop in the ring buffer).
6813  */
6814 #ifndef DOXYGEN
snd_pcm_sw_params_set_stop_threshold(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val)6815 EXPORT_SYMBOL int snd_pcm_sw_params_set_stop_threshold(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val)
6816 #else
6817 int snd_pcm_sw_params_set_stop_threshold(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val)
6818 #endif
6819 {
6820 	assert(pcm && params);
6821 	params->stop_threshold = val;
6822 	return 0;
6823 }
6824 
6825 /**
6826  * \brief Get stop threshold from a software configuration container
6827  * \param params Software configuration container
6828  * \param val Returned stop threshold in frames
6829  * \return 0 otherwise a negative error code
6830  *
6831  * PCM is automatically stopped in #SND_PCM_STATE_XRUN state when available
6832  * frames is >= threshold. If the stop threshold is equal to boundary (also
6833  * software parameter - sw_param) then automatic stop will be disabled
6834  * (thus device will do the endless loop in the ring buffer).
6835  */
6836 #ifndef DOXYGEN
snd_pcm_sw_params_get_stop_threshold(const snd_pcm_sw_params_t *params, snd_pcm_uframes_t *val)6837 EXPORT_SYMBOL int INTERNAL(snd_pcm_sw_params_get_stop_threshold)(const snd_pcm_sw_params_t *params, snd_pcm_uframes_t *val)
6838 #else
6839 int snd_pcm_sw_params_get_stop_threshold(const snd_pcm_sw_params_t *params, snd_pcm_uframes_t *val)
6840 #endif
6841 {
6842 	assert(params);
6843 	*val = params->stop_threshold;
6844 	return 0;
6845 }
6846 
6847 
6848 /**
6849  * \brief Set silence threshold inside a software configuration container
6850  * \param pcm PCM handle
6851  * \param params Software configuration container
6852  * \param val Silence threshold in frames
6853  * \return 0 otherwise a negative error code
6854  *
6855  * A portion of playback buffer is overwritten with silence (see
6856  * #snd_pcm_sw_params_set_silence_size) when playback underrun is nearer
6857  * than silence threshold.
6858  */
6859 #ifndef DOXYGEN
snd_pcm_sw_params_set_silence_threshold(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val)6860 EXPORT_SYMBOL int snd_pcm_sw_params_set_silence_threshold(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val)
6861 #else
6862 int snd_pcm_sw_params_set_silence_threshold(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val)
6863 #endif
6864 {
6865 	assert(pcm && params);
6866 	if (CHECK_SANITY(val >= pcm->buffer_size)) {
6867 		SNDMSG("invalid silent_threshold value %ld (buffer_size = %ld)",
6868 		       val, pcm->buffer_size);
6869 		return -EINVAL;
6870 	}
6871 	params->silence_threshold = val;
6872 	return 0;
6873 }
6874 
6875 /**
6876  * \brief Get silence threshold from a software configuration container
6877  * \param params Software configuration container
6878  * \param val Returned silence threshold in frames
6879  * \return 0 otherwise a negative error value
6880  *
6881  * A portion of playback buffer is overwritten with silence (see
6882  * #snd_pcm_sw_params_set_silence_size) when playback underrun is nearer
6883  * than silence threshold.
6884  */
6885 #ifndef DOXYGEN
snd_pcm_sw_params_get_silence_threshold(const snd_pcm_sw_params_t *params, snd_pcm_uframes_t *val)6886 EXPORT_SYMBOL int INTERNAL(snd_pcm_sw_params_get_silence_threshold)(const snd_pcm_sw_params_t *params, snd_pcm_uframes_t *val)
6887 #else
6888 int snd_pcm_sw_params_get_silence_threshold(const snd_pcm_sw_params_t *params, snd_pcm_uframes_t *val)
6889 #endif
6890 {
6891 	assert(params && val);
6892 	*val = params->silence_threshold;
6893 	return 0;
6894 }
6895 
6896 
6897 /**
6898  * \brief Set silence size inside a software configuration container
6899  * \param pcm PCM handle
6900  * \param params Software configuration container
6901  * \param val Silence size in frames (0 for disabled)
6902  * \return 0 otherwise a negative error code
6903  *
6904  * A portion of playback buffer is overwritten with silence when playback
6905  * underrun is nearer than silence threshold (see
6906  * #snd_pcm_sw_params_set_silence_threshold)
6907  *
6908  * When drain silence (see #snd_pcm_hw_params_get_drain_silence) is disabled,
6909  * this will also apply for draining, i.e. silence is written also when the
6910  * drain end is nearer than the silence threshold.
6911  *
6912  * The special case is when silence size value is equal or greater than
6913  * boundary. The unused portion of the ring buffer (initial written samples
6914  * are untouched) is filled with silence at start. Later, only just processed
6915  * sample area is filled with silence. Note: silence_threshold must be set to zero.
6916  */
6917 #ifndef DOXYGEN
snd_pcm_sw_params_set_silence_size(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val)6918 EXPORT_SYMBOL int snd_pcm_sw_params_set_silence_size(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val)
6919 #else
6920 int snd_pcm_sw_params_set_silence_size(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val)
6921 #endif
6922 {
6923 	assert(pcm && params);
6924 	if (CHECK_SANITY(val < pcm->boundary && val > pcm->buffer_size)) {
6925 		SNDMSG("invalid silence_size %ld (boundary %ld, buffer_size %ld)",
6926 		       val, pcm->boundary, pcm->buffer_size);
6927 		return -EINVAL;
6928 	}
6929 	params->silence_size = val;
6930 	return 0;
6931 }
6932 
6933 /**
6934  * \brief Get silence size from a software configuration container
6935  * \param params Software configuration container
6936  * \param val Returned silence size in frames (0 for disabled)
6937  * \return 0 otherwise a negative error code
6938  *
6939  * A portion of playback buffer is overwritten with silence when playback
6940  * underrun is nearer than silence threshold (see
6941  * #snd_pcm_sw_params_set_silence_threshold)
6942  */
6943 #ifndef DOXYGEN
snd_pcm_sw_params_get_silence_size(const snd_pcm_sw_params_t *params, snd_pcm_uframes_t *val)6944 EXPORT_SYMBOL int INTERNAL(snd_pcm_sw_params_get_silence_size)(const snd_pcm_sw_params_t *params, snd_pcm_uframes_t *val)
6945 #else
6946 int snd_pcm_sw_params_get_silence_size(const snd_pcm_sw_params_t *params, snd_pcm_uframes_t *val)
6947 #endif
6948 {
6949 	assert(params);
6950 	*val = params->silence_size;
6951 	return 0;
6952 }
6953 
6954 
6955 /**
6956  * \brief get size of #snd_pcm_status_t
6957  * \return size in bytes
6958  */
snd_pcm_status_sizeofnull6959 size_t snd_pcm_status_sizeof()
6960 {
6961 	return sizeof(snd_pcm_status_t);
6962 }
6963 
6964 /**
6965  * \brief allocate an invalid #snd_pcm_status_t using standard malloc
6966  * \param ptr returned pointer
6967  * \return 0 on success otherwise negative error code
6968  */
snd_pcm_status_malloc(snd_pcm_status_t **ptr)6969 int snd_pcm_status_malloc(snd_pcm_status_t **ptr)
6970 {
6971 	assert(ptr);
6972 	*ptr = calloc(1, sizeof(snd_pcm_status_t));
6973 	if (!*ptr)
6974 		return -ENOMEM;
6975 	return 0;
6976 }
6977 
6978 /**
6979  * \brief frees a previously allocated #snd_pcm_status_t
6980  * \param obj pointer to object to free
6981  */
snd_pcm_status_free(snd_pcm_status_t *obj)6982 void snd_pcm_status_free(snd_pcm_status_t *obj)
6983 {
6984 	free(obj);
6985 }
6986 
6987 /**
6988  * \brief copy one #snd_pcm_status_t to another
6989  * \param dst pointer to destination
6990  * \param src pointer to source
6991  */
snd_pcm_status_copy(snd_pcm_status_t *dst, const snd_pcm_status_t *src)6992 void snd_pcm_status_copy(snd_pcm_status_t *dst, const snd_pcm_status_t *src)
6993 {
6994 	assert(dst && src);
6995 	*dst = *src;
6996 }
6997 
6998 /**
6999  * \brief Get state from a PCM status container (see #snd_pcm_state)
7000  * \param obj #snd_pcm_status_t pointer
7001  * \return PCM state
7002  */
snd_pcm_status_get_state(const snd_pcm_status_t *obj)7003 snd_pcm_state_t snd_pcm_status_get_state(const snd_pcm_status_t *obj)
7004 {
7005 	assert(obj);
7006 	return obj->state;
7007 }
7008 
7009 /**
7010  * \brief Get trigger timestamp from a PCM status container
7011  * \param obj #snd_pcm_status_t pointer
7012  * \param ptr Pointer to returned timestamp
7013  *
7014  * Trigger means a PCM state transition (from stopped to running or
7015  * versa vice). It applies also to pause and suspend. In other words,
7016  * timestamp contains time when stream started or when it was stopped.
7017  */
snd_pcm_status_get_trigger_tstamp(const snd_pcm_status_t *obj, snd_timestamp_t *ptr)7018 void snd_pcm_status_get_trigger_tstamp(const snd_pcm_status_t *obj, snd_timestamp_t *ptr)
7019 {
7020 	assert(obj && ptr);
7021 	ptr->tv_sec = obj->trigger_tstamp.tv_sec;
7022 	ptr->tv_usec = obj->trigger_tstamp.tv_nsec / 1000L;
7023 }
7024 
7025 /**
7026  * \brief Get trigger hi-res timestamp from a PCM status container
7027  * \param obj #snd_pcm_status_t pointer
7028  * \param ptr Pointer to returned timestamp
7029  *
7030  * Trigger means a PCM state transition (from stopped to running or
7031  * versa vice). It applies also to pause and suspend. In other words,
7032  * timestamp contains time when stream started or when it was stopped.
7033  */
7034 #ifndef DOXYGEN
snd_pcm_status_get_trigger_htstamp(const snd_pcm_status_t *obj, snd_htimestamp_t *ptr)7035 EXPORT_SYMBOL void INTERNAL(snd_pcm_status_get_trigger_htstamp)(const snd_pcm_status_t *obj, snd_htimestamp_t *ptr)
7036 #else
7037 void snd_pcm_status_get_trigger_htstamp(const snd_pcm_status_t *obj, snd_htimestamp_t *ptr)
7038 #endif
7039 {
7040 	assert(obj && ptr);
7041 	*ptr = obj->trigger_tstamp;
7042 }
7043 use_default_symbol_version(__snd_pcm_status_get_trigger_htstamp, snd_pcm_status_get_trigger_htstamp, ALSA_0.9.0rc8);
7044 
7045 /**
7046  * \brief Get "now" timestamp from a PCM status container
7047  * \param obj #snd_pcm_status_t pointer
7048  * \param ptr Pointer to returned timestamp
7049  */
snd_pcm_status_get_tstamp(const snd_pcm_status_t *obj, snd_timestamp_t *ptr)7050 void snd_pcm_status_get_tstamp(const snd_pcm_status_t *obj, snd_timestamp_t *ptr)
7051 {
7052 	assert(obj && ptr);
7053 	ptr->tv_sec = obj->tstamp.tv_sec;
7054 	ptr->tv_usec = obj->tstamp.tv_nsec / 1000L;
7055 }
7056 
7057 /**
7058  * \brief Get "now" hi-res timestamp from a PCM status container
7059  * \param obj pointer to #snd_pcm_status_t
7060  * \param ptr Pointer to returned timestamp
7061  */
7062 #ifndef DOXYGEN
snd_pcm_status_get_htstamp(const snd_pcm_status_t *obj, snd_htimestamp_t *ptr)7063 EXPORT_SYMBOL void INTERNAL(snd_pcm_status_get_htstamp)(const snd_pcm_status_t *obj, snd_htimestamp_t *ptr)
7064 #else
7065 void snd_pcm_status_get_htstamp(const snd_pcm_status_t *obj, snd_htimestamp_t *ptr)
7066 #endif
7067 {
7068 	assert(obj && ptr);
7069 	*ptr = obj->tstamp;
7070 }
7071 use_default_symbol_version(__snd_pcm_status_get_htstamp, snd_pcm_status_get_htstamp, ALSA_0.9.0rc8);
7072 
7073 /**
7074  * \brief Get "now" hi-res audio timestamp from a PCM status container
7075  * \param obj pointer to #snd_pcm_status_t
7076  * \param ptr Pointer to returned timestamp
7077  */
snd_pcm_status_get_audio_htstamp(const snd_pcm_status_t *obj, snd_htimestamp_t *ptr)7078 void snd_pcm_status_get_audio_htstamp(const snd_pcm_status_t *obj, snd_htimestamp_t *ptr)
7079 {
7080 	assert(obj && ptr);
7081 	*ptr = obj->audio_tstamp;
7082 }
7083 
7084 /**
7085  * \brief Get "now" hi-res driver timestamp from a PCM status container. Defines when the status
7086  * was generated by driver, may differ from normal timestamp.
7087  * \param obj pointer to #snd_pcm_status_t
7088  * \param ptr Pointer to returned timestamp
7089  */
snd_pcm_status_get_driver_htstamp(const snd_pcm_status_t *obj, snd_htimestamp_t *ptr)7090 void snd_pcm_status_get_driver_htstamp(const snd_pcm_status_t *obj, snd_htimestamp_t *ptr)
7091 {
7092 	assert(obj && ptr);
7093 	*ptr = obj->driver_tstamp;
7094 }
7095 
7096 /**
7097  * \brief Get audio_tstamp_report from a PCM status container
7098  * \param obj pointer to #snd_pcm_status_t
7099  * \param audio_tstamp_report Pointer to returned report
7100  */
snd_pcm_status_get_audio_htstamp_report(const snd_pcm_status_t *obj, snd_pcm_audio_tstamp_report_t *audio_tstamp_report)7101 void snd_pcm_status_get_audio_htstamp_report(const snd_pcm_status_t *obj,
7102 					     snd_pcm_audio_tstamp_report_t *audio_tstamp_report)
7103 {
7104 	assert(obj && audio_tstamp_report);
7105 	snd_pcm_unpack_audio_tstamp_report(obj->audio_tstamp_data,
7106 					obj->audio_tstamp_accuracy,
7107 					audio_tstamp_report);
7108 }
7109 
7110 /**
7111  * \brief set audio_tstamp_config from a PCM status container
7112  * \param obj pointer to #snd_pcm_status_t
7113  * \param audio_tstamp_config Pointer to config (valid fields are type_requested and report_delay)
7114  */
snd_pcm_status_set_audio_htstamp_config(snd_pcm_status_t *obj, snd_pcm_audio_tstamp_config_t *audio_tstamp_config)7115 void snd_pcm_status_set_audio_htstamp_config(snd_pcm_status_t *obj,
7116 					     snd_pcm_audio_tstamp_config_t *audio_tstamp_config)
7117 {
7118 	assert(obj && audio_tstamp_config);
7119 	snd_pcm_pack_audio_tstamp_config(&obj->audio_tstamp_data, audio_tstamp_config);
7120 }
7121 
7122 /**
7123  * \brief Get delay from a PCM status container (see #snd_pcm_delay)
7124  * \return Delay in frames
7125  *
7126  * Delay is distance between current application frame position and
7127  * sound frame position.
7128  * It's positive and less than buffer size in normal situation,
7129  * negative on playback underrun and greater than buffer size on
7130  * capture overrun.
7131  */
snd_pcm_status_get_delay(const snd_pcm_status_t *obj)7132 snd_pcm_sframes_t snd_pcm_status_get_delay(const snd_pcm_status_t *obj)
7133 {
7134 	assert(obj);
7135 	return obj->delay;
7136 }
7137 
7138 /**
7139  * \brief Get number of frames available from a PCM status container (see #snd_pcm_avail_update)
7140  * \return Number of frames ready to be read/written
7141  */
snd_pcm_status_get_avail(const snd_pcm_status_t *obj)7142 snd_pcm_uframes_t snd_pcm_status_get_avail(const snd_pcm_status_t *obj)
7143 {
7144 	assert(obj);
7145 	return obj->avail;
7146 }
7147 
7148 /**
7149  * \brief Get maximum number of frames available from a PCM status container after last #snd_pcm_status call
7150  * \return Maximum number of frames ready to be read/written
7151  *
7152  * This value returns the peak for the available frames between #snd_pcm_status calls.
7153  */
snd_pcm_status_get_avail_max(const snd_pcm_status_t *obj)7154 snd_pcm_uframes_t snd_pcm_status_get_avail_max(const snd_pcm_status_t *obj)
7155 {
7156 	assert(obj);
7157 	return obj->avail_max;
7158 }
7159 
7160 /**
7161  * \brief Get count of ADC overrange detections since last call
7162  * \return Count of ADC overrange detections
7163  */
snd_pcm_status_get_overrange(const snd_pcm_status_t *obj)7164 snd_pcm_uframes_t snd_pcm_status_get_overrange(const snd_pcm_status_t *obj)
7165 {
7166 	assert(obj);
7167 	return obj->overrange;
7168 }
7169 
7170 /**
7171  * \brief get size of #snd_pcm_info_t
7172  * \return size in bytes
7173  */
snd_pcm_info_sizeofnull7174 size_t snd_pcm_info_sizeof()
7175 {
7176 	return sizeof(snd_pcm_info_t);
7177 }
7178 
7179 /**
7180  * \brief allocate an invalid #snd_pcm_info_t using standard malloc
7181  * \param ptr returned pointer
7182  * \return 0 on success otherwise negative error code
7183  */
snd_pcm_info_malloc(snd_pcm_info_t **ptr)7184 int snd_pcm_info_malloc(snd_pcm_info_t **ptr)
7185 {
7186 	assert(ptr);
7187 	*ptr = calloc(1, sizeof(snd_pcm_info_t));
7188 	if (!*ptr)
7189 		return -ENOMEM;
7190 	return 0;
7191 }
7192 
7193 /**
7194  * \brief frees a previously allocated #snd_pcm_info_t
7195  * \param obj pointer to object to free
7196  */
snd_pcm_info_free(snd_pcm_info_t *obj)7197 void snd_pcm_info_free(snd_pcm_info_t *obj)
7198 {
7199 	free(obj);
7200 }
7201 
7202 /**
7203  * \brief copy one #snd_pcm_info_t to another
7204  * \param dst pointer to destination
7205  * \param src pointer to source
7206  */
snd_pcm_info_copy(snd_pcm_info_t *dst, const snd_pcm_info_t *src)7207 void snd_pcm_info_copy(snd_pcm_info_t *dst, const snd_pcm_info_t *src)
7208 {
7209 	assert(dst && src);
7210 	*dst = *src;
7211 }
7212 
7213 /**
7214  * \brief Get device from a PCM info container
7215  * \param obj PCM info container
7216  * \return device number
7217  */
snd_pcm_info_get_device(const snd_pcm_info_t *obj)7218 unsigned int snd_pcm_info_get_device(const snd_pcm_info_t *obj)
7219 {
7220 	assert(obj);
7221 	return obj->device;
7222 }
7223 
7224 /**
7225  * \brief Get subdevice from a PCM info container
7226  * \param obj PCM info container
7227  * \return subdevice number
7228  */
snd_pcm_info_get_subdevice(const snd_pcm_info_t *obj)7229 unsigned int snd_pcm_info_get_subdevice(const snd_pcm_info_t *obj)
7230 {
7231 	assert(obj);
7232 	return obj->subdevice;
7233 }
7234 
7235 /**
7236  * \brief Get stream (direction) from a PCM info container
7237  * \param obj PCM info container
7238  * \return stream
7239  */
snd_pcm_info_get_stream(const snd_pcm_info_t *obj)7240 snd_pcm_stream_t snd_pcm_info_get_stream(const snd_pcm_info_t *obj)
7241 {
7242 	assert(obj);
7243 	return obj->stream;
7244 }
7245 
7246 /**
7247  * \brief Get card from a PCM info container
7248  * \param obj PCM info container
7249  * \return card number otherwise a negative error code if not associable to a card
7250  */
snd_pcm_info_get_card(const snd_pcm_info_t *obj)7251 int snd_pcm_info_get_card(const snd_pcm_info_t *obj)
7252 {
7253 	assert(obj);
7254 	return obj->card;
7255 }
7256 
7257 /**
7258  * \brief Get id from a PCM info container
7259  * \param obj PCM info container
7260  * \return short id of PCM
7261  */
snd_pcm_info_get_id(const snd_pcm_info_t *obj)7262 const char *snd_pcm_info_get_id(const snd_pcm_info_t *obj)
7263 {
7264 	assert(obj);
7265 	return (const char *)obj->id;
7266 }
7267 
7268 /**
7269  * \brief Get name from a PCM info container
7270  * \param obj PCM info container
7271  * \return name of PCM
7272  */
snd_pcm_info_get_name(const snd_pcm_info_t *obj)7273 const char *snd_pcm_info_get_name(const snd_pcm_info_t *obj)
7274 {
7275 	assert(obj);
7276 	return (const char *)obj->name;
7277 }
7278 
7279 /**
7280  * \brief Get subdevice name from a PCM info container
7281  * \param obj PCM info container
7282  * \return name of used PCM subdevice
7283  */
snd_pcm_info_get_subdevice_name(const snd_pcm_info_t *obj)7284 const char *snd_pcm_info_get_subdevice_name(const snd_pcm_info_t *obj)
7285 {
7286 	assert(obj);
7287 	return (const char *)obj->subname;
7288 }
7289 
7290 /**
7291  * \brief Get class from a PCM info container
7292  * \param obj PCM info container
7293  * \return class of PCM
7294  */
snd_pcm_info_get_class(const snd_pcm_info_t *obj)7295 snd_pcm_class_t snd_pcm_info_get_class(const snd_pcm_info_t *obj)
7296 {
7297 	assert(obj);
7298 	return obj->dev_class;
7299 }
7300 
7301 /**
7302  * \brief Get subclass from a PCM info container
7303  * \param obj PCM info container
7304  * \return subclass of PCM
7305  */
snd_pcm_info_get_subclass(const snd_pcm_info_t *obj)7306 snd_pcm_subclass_t snd_pcm_info_get_subclass(const snd_pcm_info_t *obj)
7307 {
7308 	assert(obj);
7309 	return obj->dev_subclass;
7310 }
7311 
7312 /**
7313  * \brief Get subdevices count from a PCM info container
7314  * \param obj PCM info container
7315  * \return subdevices total count of PCM
7316  */
snd_pcm_info_get_subdevices_count(const snd_pcm_info_t *obj)7317 unsigned int snd_pcm_info_get_subdevices_count(const snd_pcm_info_t *obj)
7318 {
7319 	assert(obj);
7320 	return obj->subdevices_count;
7321 }
7322 
7323 /**
7324  * \brief Get available subdevices count from a PCM info container
7325  * \param obj PCM info container
7326  * \return available subdevices count of PCM
7327  */
snd_pcm_info_get_subdevices_avail(const snd_pcm_info_t *obj)7328 unsigned int snd_pcm_info_get_subdevices_avail(const snd_pcm_info_t *obj)
7329 {
7330 	assert(obj);
7331 	return obj->subdevices_avail;
7332 }
7333 
7334 /**
7335  * \brief Get hardware synchronization ID from a PCM info container
7336  * \param obj PCM info container
7337  * \return hardware synchronization ID
7338  */
snd_pcm_info_get_sync(const snd_pcm_info_t *obj)7339 snd_pcm_sync_id_t snd_pcm_info_get_sync(const snd_pcm_info_t *obj)
7340 {
7341 	snd_pcm_sync_id_t res;
7342 	assert(obj);
7343 	memcpy(&res, &obj->sync, sizeof(res));
7344 	return res;
7345 }
7346 
7347 /**
7348  * \brief Set wanted device inside a PCM info container (see #snd_ctl_pcm_info)
7349  * \param obj PCM info container
7350  * \param val Device number
7351  */
snd_pcm_info_set_device(snd_pcm_info_t *obj, unsigned int val)7352 void snd_pcm_info_set_device(snd_pcm_info_t *obj, unsigned int val)
7353 {
7354 	assert(obj);
7355 	obj->device = val;
7356 }
7357 
7358 /**
7359  * \brief Set wanted subdevice inside a PCM info container (see #snd_ctl_pcm_info)
7360  * \param obj PCM info container
7361  * \param val Subdevice number
7362  */
snd_pcm_info_set_subdevice(snd_pcm_info_t *obj, unsigned int val)7363 void snd_pcm_info_set_subdevice(snd_pcm_info_t *obj, unsigned int val)
7364 {
7365 	assert(obj);
7366 	obj->subdevice = val;
7367 }
7368 
7369 /**
7370  * \brief Set wanted stream inside a PCM info container (see #snd_ctl_pcm_info)
7371  * \param obj PCM info container
7372  * \param val Stream
7373  */
snd_pcm_info_set_stream(snd_pcm_info_t *obj, snd_pcm_stream_t val)7374 void snd_pcm_info_set_stream(snd_pcm_info_t *obj, snd_pcm_stream_t val)
7375 {
7376 	assert(obj);
7377 	obj->stream = val;
7378 }
7379 
7380 /**
7381  * \brief Application request to access a portion of direct (mmap) area
7382  * \param pcm PCM handle
7383  * \param areas Returned mmap channel areas
7384  * \param offset Returned mmap area offset in area steps (== frames)
7385  * \param frames mmap area portion size in frames (wanted on entry, contiguous available on exit)
7386  * \return 0 on success otherwise a negative error code
7387  *
7388  * It is necessary to call the snd_pcm_avail_update() function directly before
7389  * this call. Otherwise, this function can return a wrong count of available frames.
7390  *
7391  * The function should be called before a sample-direct area can be accessed.
7392  * The resulting size parameter is always less or equal to the input count of frames
7393  * and can be zero, if no frames can be processed (the ring buffer is full).
7394  *
7395  * See the snd_pcm_mmap_commit() function to finish the frame processing in
7396  * the direct areas.
7397  *
7398  * The function is thread-safe when built with the proper option.
7399  */
snd_pcm_mmap_begin(snd_pcm_t *pcm, const snd_pcm_channel_area_t **areas, snd_pcm_uframes_t *offset, snd_pcm_uframes_t *frames)7400 int snd_pcm_mmap_begin(snd_pcm_t *pcm,
7401 		       const snd_pcm_channel_area_t **areas,
7402 		       snd_pcm_uframes_t *offset,
7403 		       snd_pcm_uframes_t *frames)
7404 {
7405 	int err;
7406 
7407 	err = bad_pcm_state(pcm, P_STATE_RUNNABLE, 0);
7408 	if (err < 0)
7409 		return err;
7410 	snd_pcm_lock(pcm->fast_op_arg);
7411 	err = __snd_pcm_mmap_begin(pcm, areas, offset, frames);
7412 	snd_pcm_unlock(pcm->fast_op_arg);
7413 	return err;
7414 }
7415 
7416 #ifndef DOC_HIDDEN
__snd_pcm_mmap_begin_generic(snd_pcm_t *pcm, const snd_pcm_channel_area_t **areas, snd_pcm_uframes_t *offset, snd_pcm_uframes_t *frames)7417 int __snd_pcm_mmap_begin_generic(snd_pcm_t *pcm, const snd_pcm_channel_area_t **areas,
7418 				 snd_pcm_uframes_t *offset, snd_pcm_uframes_t *frames)
7419 {
7420 	snd_pcm_uframes_t cont;
7421 	snd_pcm_uframes_t f;
7422 	snd_pcm_uframes_t avail;
7423 	const snd_pcm_channel_area_t *xareas;
7424 
7425 	assert(pcm && areas && offset && frames);
7426 
7427 	/* fallback for plugins that do not specify new callback */
7428 	xareas = snd_pcm_mmap_areas(pcm);
7429 	if (xareas == NULL)
7430 		return -EBADFD;
7431 	*areas = xareas;
7432 	*offset = *pcm->appl.ptr % pcm->buffer_size;
7433 	avail = snd_pcm_mmap_avail(pcm);
7434 	if (avail > pcm->buffer_size)
7435 		avail = pcm->buffer_size;
7436 	cont = pcm->buffer_size - *offset;
7437 	f = *frames;
7438 	if (f > avail)
7439 		f = avail;
7440 	if (f > cont)
7441 		f = cont;
7442 	*frames = f;
7443 	return 0;
7444 }
7445 
7446 /* locked version */
__snd_pcm_mmap_begin(snd_pcm_t *pcm, const snd_pcm_channel_area_t **areas, snd_pcm_uframes_t *offset, snd_pcm_uframes_t *frames)7447 int __snd_pcm_mmap_begin(snd_pcm_t *pcm, const snd_pcm_channel_area_t **areas,
7448 			 snd_pcm_uframes_t *offset, snd_pcm_uframes_t *frames)
7449 {
7450 	assert(pcm && areas && offset && frames);
7451 
7452 	if (pcm->fast_ops->mmap_begin)
7453 		return pcm->fast_ops->mmap_begin(pcm->fast_op_arg, areas, offset, frames);
7454 
7455 	return __snd_pcm_mmap_begin_generic(pcm, areas, offset, frames);
7456 }
7457 #endif
7458 
7459 /**
7460  * \brief Application has completed the access to area requested with #snd_pcm_mmap_begin
7461  * \param pcm PCM handle
7462  * \param offset area offset in area steps (== frames)
7463  * \param frames area portion size in frames
7464  * \return count of transferred frames otherwise a negative error code
7465  *
7466  * You should pass this function the offset value that
7467  * snd_pcm_mmap_begin() returned. The frames parameter should hold the
7468  * number of frames you have written or read to/from the audio
7469  * buffer. The frames parameter must never exceed the contiguous frames
7470  * count that snd_pcm_mmap_begin() returned. Each call to snd_pcm_mmap_begin()
7471  * must be followed by a call to snd_pcm_mmap_commit().
7472  *
7473  * Example:
7474 \code
7475   double phase = 0;
7476   const snd_pcm_area_t *areas;
7477   snd_pcm_sframes_t avail, size, commitres;
7478   snd_pcm_uframes_t offset, frames;
7479   int err;
7480 
7481   avail = snd_pcm_avail_update(pcm);
7482   if (avail < 0)
7483     error(avail);
7484   // at this point, we can transfer at least 'avail' frames
7485 
7486   // we want to process frames in chunks (period_size)
7487   if (avail < period_size)
7488     goto _skip;
7489   size = period_size;
7490   // it is possible that contiguous areas are smaller, thus we use a loop
7491   while (size > 0) {
7492     frames = size;
7493 
7494     err = snd_pcm_mmap_begin(pcm_handle, &areas, &offset, &frames);
7495     if (err < 0)
7496       error(err);
7497     // this function fills the areas from offset with count of frames
7498     generate_sine(areas, offset, frames, &phase);
7499     commitres = snd_pcm_mmap_commit(pcm_handle, offset, frames);
7500     if (commitres < 0 || commitres != frames)
7501       error(commitres >= 0 ? -EPIPE : commitres);
7502 
7503     size -= frames;
7504   }
7505  _skip:
7506 \endcode
7507  *
7508  * Look to the \link example_test_pcm Sine-wave generator \endlink example
7509  * for more details about the generate_sine function.
7510  *
7511  * The function is thread-safe when built with the proper option.
7512  */
snd_pcm_mmap_commit(snd_pcm_t *pcm, snd_pcm_uframes_t offset, snd_pcm_uframes_t frames)7513 snd_pcm_sframes_t snd_pcm_mmap_commit(snd_pcm_t *pcm,
7514 				      snd_pcm_uframes_t offset,
7515 				      snd_pcm_uframes_t frames)
7516 {
7517 	snd_pcm_sframes_t result;
7518 	int err;
7519 
7520 	err = bad_pcm_state(pcm, P_STATE_RUNNABLE, 0);
7521 	if (err < 0)
7522 		return err;
7523 	snd_pcm_lock(pcm->fast_op_arg);
7524 	result = __snd_pcm_mmap_commit(pcm, offset, frames);
7525 	snd_pcm_unlock(pcm->fast_op_arg);
7526 	return result;
7527 }
7528 
7529 #ifndef DOC_HIDDEN
7530 /* locked version*/
__snd_pcm_mmap_commit(snd_pcm_t *pcm, snd_pcm_uframes_t offset, snd_pcm_uframes_t frames)7531 snd_pcm_sframes_t __snd_pcm_mmap_commit(snd_pcm_t *pcm,
7532 					snd_pcm_uframes_t offset,
7533 					snd_pcm_uframes_t frames)
7534 {
7535 	assert(pcm);
7536 	if (CHECK_SANITY(offset != *pcm->appl.ptr % pcm->buffer_size)) {
7537 		SNDMSG("commit offset (%ld) doesn't match with appl_ptr (%ld) %% buf_size (%ld)",
7538 		       offset, *pcm->appl.ptr, pcm->buffer_size);
7539 		return -EPIPE;
7540 	}
7541 	if (CHECK_SANITY(frames > snd_pcm_mmap_avail(pcm))) {
7542 		SNDMSG("commit frames (%ld) overflow (avail = %ld)", frames,
7543 		       snd_pcm_mmap_avail(pcm));
7544 		return -EPIPE;
7545 	}
7546 	if (pcm->fast_ops->mmap_commit)
7547 		return pcm->fast_ops->mmap_commit(pcm->fast_op_arg, offset, frames);
7548 	else
7549 		return -ENOSYS;
7550 }
7551 
_snd_pcm_poll_descriptor(snd_pcm_t *pcm)7552 int _snd_pcm_poll_descriptor(snd_pcm_t *pcm)
7553 {
7554 	assert(pcm);
7555 	return pcm->poll_fd;
7556 }
7557 
snd_pcm_areas_from_buf(snd_pcm_t *pcm, snd_pcm_channel_area_t *areas, void *buf)7558 void snd_pcm_areas_from_buf(snd_pcm_t *pcm, snd_pcm_channel_area_t *areas,
7559 			    void *buf)
7560 {
7561 	unsigned int channel;
7562 	unsigned int channels;
7563 
7564 	snd_pcm_lock(pcm);
7565 	channels = pcm->channels;
7566 	for (channel = 0; channel < channels; ++channel, ++areas) {
7567 		areas->addr = buf;
7568 		areas->first = channel * pcm->sample_bits;
7569 		areas->step = pcm->frame_bits;
7570 	}
7571 	snd_pcm_unlock(pcm);
7572 }
7573 
snd_pcm_areas_from_bufs(snd_pcm_t *pcm, snd_pcm_channel_area_t *areas, void **bufs)7574 void snd_pcm_areas_from_bufs(snd_pcm_t *pcm, snd_pcm_channel_area_t *areas,
7575 			     void **bufs)
7576 {
7577 	unsigned int channel;
7578 	unsigned int channels;
7579 
7580 	snd_pcm_lock(pcm);
7581 	channels = pcm->channels;
7582 	for (channel = 0; channel < channels; ++channel, ++areas, ++bufs) {
7583 		areas->addr = *bufs;
7584 		areas->first = 0;
7585 		areas->step = pcm->sample_bits;
7586 	}
7587 	snd_pcm_unlock(pcm);
7588 }
7589 
snd_pcm_read_areas(snd_pcm_t *pcm, const snd_pcm_channel_area_t *areas, snd_pcm_uframes_t offset, snd_pcm_uframes_t size, snd_pcm_xfer_areas_func_t func)7590 snd_pcm_sframes_t snd_pcm_read_areas(snd_pcm_t *pcm, const snd_pcm_channel_area_t *areas,
7591 				     snd_pcm_uframes_t offset, snd_pcm_uframes_t size,
7592 				     snd_pcm_xfer_areas_func_t func)
7593 {
7594 	snd_pcm_uframes_t xfer = 0;
7595 	snd_pcm_sframes_t err = 0;
7596 	snd_pcm_state_t state;
7597 
7598 	if (size == 0)
7599 		return 0;
7600 
7601 	__snd_pcm_lock(pcm->fast_op_arg); /* forced lock */
7602 	while (size > 0) {
7603 		snd_pcm_uframes_t frames;
7604 		snd_pcm_sframes_t avail;
7605 	_again:
7606 		state = __snd_pcm_state(pcm);
7607 		switch (state) {
7608 		case SND_PCM_STATE_PREPARED:
7609 			err = __snd_pcm_start(pcm);
7610 			if (err < 0)
7611 				goto _end;
7612 			break;
7613 		case SND_PCM_STATE_RUNNING:
7614 			err = __snd_pcm_hwsync(pcm);
7615 			if (err < 0)
7616 				goto _end;
7617 			break;
7618 		case SND_PCM_STATE_DRAINING:
7619 		case SND_PCM_STATE_PAUSED:
7620 			break;
7621 		default:
7622 			err = pcm_state_to_error(state);
7623 			if (!err)
7624 				err = -EBADFD;
7625 			goto _end;
7626 		}
7627 		avail = __snd_pcm_avail_update(pcm);
7628 		if (avail < 0) {
7629 			err = avail;
7630 			goto _end;
7631 		}
7632 		if (avail == 0) {
7633 			if (state == SND_PCM_STATE_DRAINING)
7634 				goto _end;
7635 			if (pcm->mode & SND_PCM_NONBLOCK) {
7636 				err = -EAGAIN;
7637 				goto _end;
7638 			}
7639 
7640 			err = __snd_pcm_wait_in_lock(pcm, SND_PCM_WAIT_IO);
7641 			if (err < 0)
7642 				break;
7643 			goto _again;
7644 
7645 		}
7646 		frames = size;
7647 		if (frames > (snd_pcm_uframes_t) avail)
7648 			frames = avail;
7649 		if (! frames)
7650 			break;
7651 		err = func(pcm, areas, offset, frames);
7652 		if (err < 0)
7653 			break;
7654 		frames = err;
7655 		offset += frames;
7656 		size -= frames;
7657 		xfer += frames;
7658 	}
7659  _end:
7660 	__snd_pcm_unlock(pcm->fast_op_arg);
7661 	return xfer > 0 ? (snd_pcm_sframes_t) xfer : snd_pcm_check_error(pcm, err);
7662 }
7663 
snd_pcm_write_areas(snd_pcm_t *pcm, const snd_pcm_channel_area_t *areas, snd_pcm_uframes_t offset, snd_pcm_uframes_t size, snd_pcm_xfer_areas_func_t func)7664 snd_pcm_sframes_t snd_pcm_write_areas(snd_pcm_t *pcm, const snd_pcm_channel_area_t *areas,
7665 				      snd_pcm_uframes_t offset, snd_pcm_uframes_t size,
7666 				      snd_pcm_xfer_areas_func_t func)
7667 {
7668 	snd_pcm_uframes_t xfer = 0;
7669 	snd_pcm_sframes_t err = 0;
7670 	snd_pcm_state_t state;
7671 
7672 	if (size == 0)
7673 		return 0;
7674 
7675 	__snd_pcm_lock(pcm->fast_op_arg); /* forced lock */
7676 	while (size > 0) {
7677 		snd_pcm_uframes_t frames;
7678 		snd_pcm_sframes_t avail;
7679 	_again:
7680 		state = __snd_pcm_state(pcm);
7681 		switch (state) {
7682 		case SND_PCM_STATE_PREPARED:
7683 		case SND_PCM_STATE_PAUSED:
7684 			break;
7685 		case SND_PCM_STATE_RUNNING:
7686 			err = __snd_pcm_hwsync(pcm);
7687 			if (err < 0)
7688 				goto _end;
7689 			break;
7690 		default:
7691 			err = pcm_state_to_error(state);
7692 			if (!err)
7693 				err = -EBADFD;
7694 			goto _end;
7695 		}
7696 		avail = __snd_pcm_avail_update(pcm);
7697 		if (avail < 0) {
7698 			err = avail;
7699 			goto _end;
7700 		}
7701 		if (state == SND_PCM_STATE_RUNNING &&
7702 		    size > (snd_pcm_uframes_t)avail) {
7703 			if (snd_pcm_may_wait_for_avail_min(pcm, avail)) {
7704 				if (pcm->mode & SND_PCM_NONBLOCK) {
7705 					err = -EAGAIN;
7706 					goto _end;
7707 				}
7708 
7709 				err = snd_pcm_wait_nocheck(pcm, SND_PCM_WAIT_IO);
7710 				if (err < 0)
7711 					break;
7712 				goto _again;
7713 			}
7714 			/* the snd_pcm_may_wait_for_avail_min may check against the
7715 			 * updated hw.ptr (slaves), get the avail again here
7716 			 */
7717 			avail = __snd_pcm_avail_update(pcm);
7718 			if (avail < 0) {
7719 				err = avail;
7720 				goto _end;
7721 			}
7722 		}
7723 		frames = size;
7724 		if (frames > (snd_pcm_uframes_t) avail)
7725 			frames = avail;
7726 		if (! frames)
7727 			break;
7728 		err = func(pcm, areas, offset, frames);
7729 		if (err < 0)
7730 			break;
7731 		frames = err;
7732 		if (state == SND_PCM_STATE_PREPARED) {
7733 			snd_pcm_sframes_t hw_avail = pcm->buffer_size - avail;
7734 			hw_avail += frames;
7735 			/* some plugins might automatically start the stream */
7736 			state = __snd_pcm_state(pcm);
7737 			if (state == SND_PCM_STATE_PREPARED &&
7738 			    hw_avail >= 0 &&
7739 			    (snd_pcm_uframes_t) hw_avail >= pcm->start_threshold) {
7740 				err = __snd_pcm_start(pcm);
7741 				if (err < 0)
7742 					goto _end;
7743 			}
7744 		}
7745 		offset += frames;
7746 		size -= frames;
7747 		xfer += frames;
7748 	}
7749  _end:
7750 	__snd_pcm_unlock(pcm->fast_op_arg);
7751 	return xfer > 0 ? (snd_pcm_sframes_t) xfer : snd_pcm_check_error(pcm, err);
7752 }
7753 
_snd_pcm_mmap_hw_ptr(snd_pcm_t *pcm)7754 snd_pcm_uframes_t _snd_pcm_mmap_hw_ptr(snd_pcm_t *pcm)
7755 {
7756 	return *pcm->hw.ptr;
7757 }
7758 
_snd_pcm_boundary(snd_pcm_t *pcm)7759 snd_pcm_uframes_t _snd_pcm_boundary(snd_pcm_t *pcm)
7760 {
7761 	return pcm->boundary;
7762 }
7763 
7764 #ifndef DOC_HIDDEN
7765 link_warning(_snd_pcm_mmap_hw_ptr, "Warning: _snd_pcm_mmap_hw_ptr() is deprecated, consider to not use this function");
7766 link_warning(_snd_pcm_boundary, "Warning: _snd_pcm_boundary() is deprecated, consider to use snd_pcm_sw_params_current()");
7767 #endif
7768 
7769 static const char *const names[SND_PCM_HW_PARAM_LAST_INTERVAL + 1] = {
7770 	[SND_PCM_HW_PARAM_FORMAT] = "format",
7771 	[SND_PCM_HW_PARAM_CHANNELS] = "channels",
7772 	[SND_PCM_HW_PARAM_RATE] = "rate",
7773 	[SND_PCM_HW_PARAM_PERIOD_TIME] = "period_time",
7774 	[SND_PCM_HW_PARAM_PERIOD_SIZE] = "period_size",
7775 	[SND_PCM_HW_PARAM_BUFFER_TIME] = "buffer_time",
7776 	[SND_PCM_HW_PARAM_BUFFER_SIZE] = "buffer_size",
7777 	[SND_PCM_HW_PARAM_PERIODS] = "periods"
7778 };
7779 
snd_pcm_slave_conf(snd_config_t *root, snd_config_t *conf, snd_config_t **_pcm_conf, unsigned int count, ...)7780 int snd_pcm_slave_conf(snd_config_t *root, snd_config_t *conf,
7781 		       snd_config_t **_pcm_conf, unsigned int count, ...)
7782 {
7783 	snd_config_iterator_t i, next;
7784 	const char *str;
7785 	struct {
7786 		unsigned int index;
7787 		int flags;
7788 		void *ptr;
7789 		int present;
7790 	} fields[count];
7791 	unsigned int k;
7792 	snd_config_t *pcm_conf = NULL;
7793 	int err;
7794 	int to_free = 0;
7795 	va_list args;
7796 	assert(root);
7797 	assert(conf);
7798 	assert(_pcm_conf);
7799 	if (snd_config_get_string(conf, &str) >= 0) {
7800 		err = snd_config_search_definition(root, "pcm_slave", str, &conf);
7801 		if (err < 0) {
7802 			SNDERR("Invalid slave definition");
7803 			return -EINVAL;
7804 		}
7805 		to_free = 1;
7806 	}
7807 	if (snd_config_get_type(conf) != SND_CONFIG_TYPE_COMPOUND) {
7808 		SNDERR("Invalid slave definition");
7809 		err = -EINVAL;
7810 		goto _err;
7811 	}
7812 	va_start(args, count);
7813 	for (k = 0; k < count; ++k) {
7814 		fields[k].index = va_arg(args, int);
7815 		fields[k].flags = va_arg(args, int);
7816 		fields[k].ptr = va_arg(args, void *);
7817 		fields[k].present = 0;
7818 	}
7819 	va_end(args);
7820 	snd_config_for_each(i, next, conf) {
7821 		snd_config_t *n = snd_config_iterator_entry(i);
7822 		const char *id;
7823 		if (snd_config_get_id(n, &id) < 0)
7824 			continue;
7825 		if (strcmp(id, "comment") == 0)
7826 			continue;
7827 		if (strcmp(id, "pcm") == 0) {
7828 			if (pcm_conf != NULL)
7829 				snd_config_delete(pcm_conf);
7830 			if ((err = snd_config_copy(&pcm_conf, n)) < 0)
7831 				goto _err;
7832 			continue;
7833 		}
7834 		for (k = 0; k < count; ++k) {
7835 			unsigned int idx = fields[k].index;
7836 			long v;
7837 			assert(idx < SND_PCM_HW_PARAM_LAST_INTERVAL);
7838 			assert(names[idx]);
7839 			if (strcmp(id, names[idx]) != 0)
7840 				continue;
7841 			switch (idx) {
7842 			case SND_PCM_HW_PARAM_FORMAT:
7843 			{
7844 				snd_pcm_format_t f;
7845 				err = snd_config_get_string(n, &str);
7846 				if (err < 0) {
7847 				_invalid:
7848 					SNDERR("invalid type for %s", id);
7849 					goto _err;
7850 				}
7851 				if ((fields[k].flags & SCONF_UNCHANGED) &&
7852 				    strcasecmp(str, "unchanged") == 0) {
7853 					*(snd_pcm_format_t*)fields[k].ptr = (snd_pcm_format_t) -2;
7854 					break;
7855 				}
7856 				f = snd_pcm_format_value(str);
7857 				if (f == SND_PCM_FORMAT_UNKNOWN) {
7858 					SNDERR("unknown format %s", str);
7859 					err = -EINVAL;
7860 					goto _err;
7861 				}
7862 				*(snd_pcm_format_t*)fields[k].ptr = f;
7863 				break;
7864 			}
7865 			default:
7866 				if ((fields[k].flags & SCONF_UNCHANGED)) {
7867 					err = snd_config_get_string(n, &str);
7868 					if (err >= 0 &&
7869 					    strcasecmp(str, "unchanged") == 0) {
7870 						*(int*)fields[k].ptr = -2;
7871 						break;
7872 					}
7873 				}
7874 				err = snd_config_get_integer(n, &v);
7875 				if (err < 0)
7876 					goto _invalid;
7877 				*(int*)fields[k].ptr = v;
7878 				break;
7879 			}
7880 			fields[k].present = 1;
7881 			break;
7882 		}
7883 		if (k < count)
7884 			continue;
7885 		SNDERR("Unknown field %s", id);
7886 		err = -EINVAL;
7887 		goto _err;
7888 	}
7889 	if (!pcm_conf) {
7890 		SNDERR("missing field pcm");
7891 		err = -EINVAL;
7892 		goto _err;
7893 	}
7894 	for (k = 0; k < count; ++k) {
7895 		if ((fields[k].flags & SCONF_MANDATORY) && !fields[k].present) {
7896 			SNDERR("missing field %s", names[fields[k].index]);
7897 			err = -EINVAL;
7898 			goto _err;
7899 		}
7900 	}
7901 	*_pcm_conf = pcm_conf;
7902 	pcm_conf = NULL;
7903 	err = 0;
7904  _err:
7905  	if (pcm_conf)
7906  		snd_config_delete(pcm_conf);
7907 	if (to_free)
7908 		snd_config_delete(conf);
7909 	return err;
7910 }
7911 
snd_pcm_set_ptr(snd_pcm_t *pcm, snd_pcm_rbptr_t *rbptr, volatile snd_pcm_uframes_t *hw_ptr, int fd, off_t offset)7912 static void snd_pcm_set_ptr(snd_pcm_t *pcm, snd_pcm_rbptr_t *rbptr,
7913 			    volatile snd_pcm_uframes_t *hw_ptr, int fd, off_t offset)
7914 {
7915 	rbptr->master = NULL;	/* I'm master */
7916 	rbptr->ptr = hw_ptr;
7917 	rbptr->fd = fd;
7918 	rbptr->offset = offset;
7919 	if (rbptr->changed)
7920 		rbptr->changed(pcm, NULL);
7921 }
7922 
snd_pcm_set_hw_ptr(snd_pcm_t *pcm, volatile snd_pcm_uframes_t *hw_ptr, int fd, off_t offset)7923 void snd_pcm_set_hw_ptr(snd_pcm_t *pcm, volatile snd_pcm_uframes_t *hw_ptr, int fd, off_t offset)
7924 {
7925 	assert(pcm);
7926 	assert(hw_ptr);
7927 	snd_pcm_set_ptr(pcm, &pcm->hw, hw_ptr, fd, offset);
7928 }
7929 
snd_pcm_set_appl_ptr(snd_pcm_t *pcm, volatile snd_pcm_uframes_t *appl_ptr, int fd, off_t offset)7930 void snd_pcm_set_appl_ptr(snd_pcm_t *pcm, volatile snd_pcm_uframes_t *appl_ptr, int fd, off_t offset)
7931 {
7932 	assert(pcm);
7933 	assert(appl_ptr);
7934 	snd_pcm_set_ptr(pcm, &pcm->appl, appl_ptr, fd, offset);
7935 }
7936 
snd_pcm_link_ptr(snd_pcm_t *pcm, snd_pcm_rbptr_t *pcm_rbptr, snd_pcm_t *slave, snd_pcm_rbptr_t *slave_rbptr)7937 static void snd_pcm_link_ptr(snd_pcm_t *pcm, snd_pcm_rbptr_t *pcm_rbptr,
7938 			     snd_pcm_t *slave, snd_pcm_rbptr_t *slave_rbptr)
7939 {
7940 	snd_pcm_t **a;
7941 	int idx;
7942 
7943 	a = slave_rbptr->link_dst;
7944 	for (idx = 0; idx < slave_rbptr->link_dst_count; idx++)
7945 		if (a[idx] == NULL) {
7946 			a[idx] = pcm;
7947 			goto __found_free_place;
7948 		}
7949 	a = realloc(a, sizeof(snd_pcm_t *) * (slave_rbptr->link_dst_count + 1));
7950 	if (a == NULL) {
7951 		pcm_rbptr->ptr = NULL;
7952 		pcm_rbptr->fd = -1;
7953 		pcm_rbptr->offset = 0UL;
7954 		return;
7955 	}
7956 	a[slave_rbptr->link_dst_count++] = pcm;
7957       __found_free_place:
7958 	pcm_rbptr->master = slave_rbptr->master ? slave_rbptr->master : slave;
7959 	pcm_rbptr->ptr = slave_rbptr->ptr;
7960 	pcm_rbptr->fd = slave_rbptr->fd;
7961 	pcm_rbptr->offset = slave_rbptr->offset;
7962 	slave_rbptr->link_dst = a;
7963 	if (pcm_rbptr->changed)
7964 		pcm_rbptr->changed(pcm, slave);
7965 }
7966 
snd_pcm_unlink_ptr(snd_pcm_t *pcm, snd_pcm_rbptr_t *pcm_rbptr, snd_pcm_t *slave, snd_pcm_rbptr_t *slave_rbptr)7967 static void snd_pcm_unlink_ptr(snd_pcm_t *pcm, snd_pcm_rbptr_t *pcm_rbptr,
7968 			       snd_pcm_t *slave, snd_pcm_rbptr_t *slave_rbptr)
7969 {
7970 	snd_pcm_t **a;
7971 	int idx;
7972 
7973 	a = slave_rbptr->link_dst;
7974 	for (idx = 0; idx < slave_rbptr->link_dst_count; idx++) {
7975 		if (a[idx] == pcm) {
7976 			a[idx] = NULL;
7977 			goto __found;
7978 		}
7979 	}
7980 	/* assert(0); */
7981 	return;
7982 
7983       __found:
7984       	pcm_rbptr->master = NULL;
7985 	pcm_rbptr->ptr = NULL;
7986 	pcm_rbptr->fd = -1;
7987 	pcm_rbptr->offset = 0UL;
7988 	if (pcm_rbptr->changed)
7989 		pcm_rbptr->changed(pcm, slave);
7990 }
7991 
snd_pcm_link_hw_ptr(snd_pcm_t *pcm, snd_pcm_t *slave)7992 void snd_pcm_link_hw_ptr(snd_pcm_t *pcm, snd_pcm_t *slave)
7993 {
7994 	assert(pcm);
7995 	assert(slave);
7996 	snd_pcm_link_ptr(pcm, &pcm->hw, slave, &slave->hw);
7997 }
7998 
snd_pcm_link_appl_ptr(snd_pcm_t *pcm, snd_pcm_t *slave)7999 void snd_pcm_link_appl_ptr(snd_pcm_t *pcm, snd_pcm_t *slave)
8000 {
8001 	assert(pcm);
8002 	assert(slave);
8003 	snd_pcm_link_ptr(pcm, &pcm->appl, slave, &slave->appl);
8004 }
8005 
snd_pcm_unlink_hw_ptr(snd_pcm_t *pcm, snd_pcm_t *slave)8006 void snd_pcm_unlink_hw_ptr(snd_pcm_t *pcm, snd_pcm_t *slave)
8007 {
8008 	assert(pcm);
8009 	assert(slave);
8010 	snd_pcm_unlink_ptr(pcm, &pcm->hw, slave, &slave->hw);
8011 }
8012 
snd_pcm_unlink_appl_ptr(snd_pcm_t *pcm, snd_pcm_t *slave)8013 void snd_pcm_unlink_appl_ptr(snd_pcm_t *pcm, snd_pcm_t *slave)
8014 {
8015 	assert(pcm);
8016 	assert(slave);
8017 	snd_pcm_unlink_ptr(pcm, &pcm->appl, slave, &slave->appl);
8018 }
8019 
8020 #endif /* DOC_HIDDEN */
8021 
8022 /*
8023  *
8024  */
8025 
8026 #ifndef DOC_HIDDEN
8027 
8028 #ifdef USE_VERSIONED_SYMBOLS
8029 
8030 #define OBSOLETE1(name, what, new) \
8031   default_symbol_version(__##name, name, new); \
8032   symbol_version(__old_##name, name, what);
8033 
8034 #else
8035 
8036 #define OBSOLETE1(name, what, new) \
8037   use_default_symbol_version(__##name, name, new);
8038 
8039 #endif /* USE_VERSIONED_SYMBOLS */
8040 
8041 #define __P_OLD_GET(pfx, name, val_type, ret_type) \
8042 EXPORT_SYMBOL ret_type pfx##name(const snd_pcm_hw_params_t *params) \
8043 { \
8044 	val_type val; \
8045 	if (INTERNAL(name)(params, &val) < 0) \
8046 		return 0; \
8047 	return (ret_type)val; \
8048 }
8049 
8050 #define __P_OLD_GET1(pfx, name, val_type, ret_type) \
8051 EXPORT_SYMBOL ret_type pfx##name(const snd_pcm_hw_params_t *params, int *dir) \
8052 { \
8053 	val_type val; \
8054 	if (INTERNAL(name)(params, &val, dir) < 0) \
8055 		return 0; \
8056 	return (ret_type)val; \
8057 }
8058 
8059 #define __OLD_GET(name, val_type, ret_type) __P_OLD_GET(__old_, name, val_type, ret_type)
8060 #define __OLD_GET1(name, val_type, ret_type) __P_OLD_GET1(__old_, name, val_type, ret_type)
8061 
8062 __OLD_GET(snd_pcm_hw_params_get_access, snd_pcm_access_t, int);
8063 __OLD_GET(snd_pcm_hw_params_get_format, snd_pcm_format_t, int);
8064 __OLD_GET(snd_pcm_hw_params_get_subformat, snd_pcm_subformat_t, int);
8065 __OLD_GET(snd_pcm_hw_params_get_channels, unsigned int, int);
8066 __OLD_GET1(snd_pcm_hw_params_get_rate, unsigned int, int);
8067 __OLD_GET1(snd_pcm_hw_params_get_period_time, unsigned int, int);
8068 __OLD_GET1(snd_pcm_hw_params_get_period_size, snd_pcm_uframes_t, snd_pcm_sframes_t);
8069 __OLD_GET1(snd_pcm_hw_params_get_periods, unsigned int, int);
8070 __OLD_GET1(snd_pcm_hw_params_get_buffer_time, unsigned int, int);
8071 __OLD_GET(snd_pcm_hw_params_get_buffer_size, snd_pcm_uframes_t, snd_pcm_sframes_t);
8072 __OLD_GET1(snd_pcm_hw_params_get_tick_time, unsigned int, int);
8073 
8074 __OLD_GET(snd_pcm_hw_params_get_channels_min, unsigned int, unsigned int);
8075 __OLD_GET1(snd_pcm_hw_params_get_rate_min, unsigned int, unsigned int);
8076 __OLD_GET1(snd_pcm_hw_params_get_period_time_min, unsigned int, unsigned int);
8077 __OLD_GET1(snd_pcm_hw_params_get_period_size_min, snd_pcm_uframes_t, snd_pcm_uframes_t);
8078 __OLD_GET1(snd_pcm_hw_params_get_periods_min, unsigned int, unsigned int);
8079 __OLD_GET1(snd_pcm_hw_params_get_buffer_time_min, unsigned int, unsigned int);
8080 __OLD_GET(snd_pcm_hw_params_get_buffer_size_min, snd_pcm_uframes_t, snd_pcm_uframes_t);
8081 __OLD_GET1(snd_pcm_hw_params_get_tick_time_min, unsigned int, unsigned int);
8082 
8083 __OLD_GET(snd_pcm_hw_params_get_channels_max, unsigned int, unsigned int);
8084 __OLD_GET1(snd_pcm_hw_params_get_rate_max, unsigned int, unsigned int);
8085 __OLD_GET1(snd_pcm_hw_params_get_period_time_max, unsigned int, unsigned int);
8086 __OLD_GET1(snd_pcm_hw_params_get_period_size_max, snd_pcm_uframes_t, snd_pcm_uframes_t);
8087 __OLD_GET1(snd_pcm_hw_params_get_periods_max, unsigned int, unsigned int);
8088 __OLD_GET1(snd_pcm_hw_params_get_buffer_time_max, unsigned int, unsigned int);
8089 __OLD_GET(snd_pcm_hw_params_get_buffer_size_max, snd_pcm_uframes_t, snd_pcm_uframes_t);
8090 __OLD_GET1(snd_pcm_hw_params_get_tick_time_max, unsigned int, unsigned int);
8091 
8092 #define __P_OLD_NEAR(pfx, name, ret_type) \
8093 EXPORT_SYMBOL ret_type pfx##name(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, ret_type val) \
8094 { \
8095 	if (INTERNAL(name)(pcm, params, &val) < 0) \
8096 		return 0; \
8097 	return (ret_type)val; \
8098 }
8099 
8100 #define __P_OLD_NEAR1(pfx, name, ret_type) \
8101 EXPORT_SYMBOL ret_type pfx##name(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, ret_type val, int *dir) \
8102 { \
8103 	if (INTERNAL(name)(pcm, params, &val, dir) < 0) \
8104 		return 0; \
8105 	return (ret_type)val; \
8106 }
8107 
8108 #define __OLD_NEAR(name, ret_type) __P_OLD_NEAR(__old_, name, ret_type)
8109 #define __OLD_NEAR1(name, ret_type) __P_OLD_NEAR1(__old_, name, ret_type)
8110 
8111 __OLD_NEAR(snd_pcm_hw_params_set_channels_near, unsigned int);
8112 __OLD_NEAR1(snd_pcm_hw_params_set_rate_near, unsigned int);
8113 __OLD_NEAR1(snd_pcm_hw_params_set_period_time_near, unsigned int);
8114 __OLD_NEAR1(snd_pcm_hw_params_set_period_size_near, snd_pcm_uframes_t);
8115 __OLD_NEAR1(snd_pcm_hw_params_set_periods_near, unsigned int);
8116 __OLD_NEAR1(snd_pcm_hw_params_set_buffer_time_near, unsigned int);
8117 __OLD_NEAR(snd_pcm_hw_params_set_buffer_size_near, snd_pcm_uframes_t);
8118 __OLD_NEAR1(snd_pcm_hw_params_set_tick_time_near, unsigned int);
8119 
8120 #define __P_OLD_SET_FL(pfx, name, ret_type) \
8121 EXPORT_SYMBOL ret_type pfx##name(snd_pcm_t *pcm, snd_pcm_hw_params_t *params) \
8122 { \
8123 	ret_type val; \
8124 	if (INTERNAL(name)(pcm, params, &val) < 0) \
8125 		return 0; \
8126 	return (ret_type)val; \
8127 }
8128 
8129 #define __P_OLD_SET_FL1(pfx, name, ret_type) \
8130 EXPORT_SYMBOL ret_type pfx##name(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir) \
8131 { \
8132 	ret_type val; \
8133 	if (INTERNAL(name)(pcm, params, &val, dir) < 0) \
8134 		return 0; \
8135 	return (ret_type)val; \
8136 }
8137 
8138 #define __OLD_SET_FL(name, ret_type) __P_OLD_SET_FL(__old_, name, ret_type)
8139 #define __OLD_SET_FL1(name, ret_type) __P_OLD_SET_FL1(__old_, name, ret_type)
8140 
8141 __OLD_SET_FL(snd_pcm_hw_params_set_access_first, snd_pcm_access_t);
8142 __OLD_SET_FL(snd_pcm_hw_params_set_format_first, snd_pcm_format_t);
8143 __OLD_SET_FL(snd_pcm_hw_params_set_subformat_first, snd_pcm_subformat_t);
8144 __OLD_SET_FL(snd_pcm_hw_params_set_channels_first, unsigned int);
8145 __OLD_SET_FL1(snd_pcm_hw_params_set_rate_first, unsigned int);
8146 __OLD_SET_FL1(snd_pcm_hw_params_set_period_time_first, unsigned int);
8147 __OLD_SET_FL1(snd_pcm_hw_params_set_period_size_first, snd_pcm_uframes_t);
8148 __OLD_SET_FL1(snd_pcm_hw_params_set_periods_first, unsigned int);
8149 __OLD_SET_FL1(snd_pcm_hw_params_set_buffer_time_first, unsigned int);
8150 __OLD_SET_FL(snd_pcm_hw_params_set_buffer_size_first, snd_pcm_uframes_t);
8151 __OLD_SET_FL1(snd_pcm_hw_params_set_tick_time_first, unsigned int);
8152 
8153 __OLD_SET_FL(snd_pcm_hw_params_set_access_last, snd_pcm_access_t);
8154 __OLD_SET_FL(snd_pcm_hw_params_set_format_last, snd_pcm_format_t);
8155 __OLD_SET_FL(snd_pcm_hw_params_set_subformat_last, snd_pcm_subformat_t);
8156 __OLD_SET_FL(snd_pcm_hw_params_set_channels_last, unsigned int);
8157 __OLD_SET_FL1(snd_pcm_hw_params_set_rate_last, unsigned int);
8158 __OLD_SET_FL1(snd_pcm_hw_params_set_period_time_last, unsigned int);
8159 __OLD_SET_FL1(snd_pcm_hw_params_set_period_size_last, snd_pcm_uframes_t);
8160 __OLD_SET_FL1(snd_pcm_hw_params_set_periods_last, unsigned int);
8161 __OLD_SET_FL1(snd_pcm_hw_params_set_buffer_time_last, unsigned int);
8162 __OLD_SET_FL(snd_pcm_hw_params_set_buffer_size_last, snd_pcm_uframes_t);
8163 __OLD_SET_FL1(snd_pcm_hw_params_set_tick_time_last, unsigned int);
8164 
8165 #define __P_OLD_GET_SW(pfx, name, ret_type) \
8166 EXPORT_SYMBOL ret_type pfx##name(snd_pcm_sw_params_t *params) \
8167 { \
8168 	ret_type val; \
8169 	if (INTERNAL(name)(params, &val) < 0) \
8170 		return 0; \
8171 	return (ret_type)val; \
8172 }
8173 
8174 #define __OLD_GET_SW(name, ret_type) __P_OLD_GET_SW(__old_, name, ret_type)
8175 
8176 __OLD_GET_SW(snd_pcm_sw_params_get_tstamp_mode, snd_pcm_tstamp_t);
8177 __OLD_GET_SW(snd_pcm_sw_params_get_sleep_min, unsigned int);
8178 __OLD_GET_SW(snd_pcm_sw_params_get_avail_min, snd_pcm_uframes_t);
8179 __OLD_GET_SW(snd_pcm_sw_params_get_xfer_align, snd_pcm_uframes_t);
8180 __OLD_GET_SW(snd_pcm_sw_params_get_start_threshold, snd_pcm_uframes_t);
8181 __OLD_GET_SW(snd_pcm_sw_params_get_stop_threshold, snd_pcm_uframes_t);
8182 __OLD_GET_SW(snd_pcm_sw_params_get_silence_threshold, snd_pcm_uframes_t);
8183 __OLD_GET_SW(snd_pcm_sw_params_get_silence_size, snd_pcm_uframes_t);
8184 
8185 OBSOLETE1(snd_pcm_hw_params_get_access, ALSA_0.9, ALSA_0.9.0rc4);
8186 OBSOLETE1(snd_pcm_hw_params_set_access_first, ALSA_0.9, ALSA_0.9.0rc4);
8187 OBSOLETE1(snd_pcm_hw_params_set_access_last, ALSA_0.9, ALSA_0.9.0rc4);
8188 
8189 OBSOLETE1(snd_pcm_hw_params_get_format, ALSA_0.9, ALSA_0.9.0rc4);
8190 OBSOLETE1(snd_pcm_hw_params_set_format_first, ALSA_0.9, ALSA_0.9.0rc4);
8191 OBSOLETE1(snd_pcm_hw_params_set_format_last, ALSA_0.9, ALSA_0.9.0rc4);
8192 
8193 OBSOLETE1(snd_pcm_hw_params_get_subformat, ALSA_0.9, ALSA_0.9.0rc4);
8194 OBSOLETE1(snd_pcm_hw_params_set_subformat_first, ALSA_0.9, ALSA_0.9.0rc4);
8195 OBSOLETE1(snd_pcm_hw_params_set_subformat_last, ALSA_0.9, ALSA_0.9.0rc4);
8196 
8197 OBSOLETE1(snd_pcm_hw_params_get_channels, ALSA_0.9, ALSA_0.9.0rc4);
8198 OBSOLETE1(snd_pcm_hw_params_get_channels_min, ALSA_0.9, ALSA_0.9.0rc4);
8199 OBSOLETE1(snd_pcm_hw_params_get_channels_max, ALSA_0.9, ALSA_0.9.0rc4);
8200 OBSOLETE1(snd_pcm_hw_params_set_channels_near, ALSA_0.9, ALSA_0.9.0rc4);
8201 OBSOLETE1(snd_pcm_hw_params_set_channels_first, ALSA_0.9, ALSA_0.9.0rc4);
8202 OBSOLETE1(snd_pcm_hw_params_set_channels_last, ALSA_0.9, ALSA_0.9.0rc4);
8203 
8204 OBSOLETE1(snd_pcm_hw_params_get_rate, ALSA_0.9, ALSA_0.9.0rc4);
8205 OBSOLETE1(snd_pcm_hw_params_get_rate_min, ALSA_0.9, ALSA_0.9.0rc4);
8206 OBSOLETE1(snd_pcm_hw_params_get_rate_max, ALSA_0.9, ALSA_0.9.0rc4);
8207 OBSOLETE1(snd_pcm_hw_params_set_rate_near, ALSA_0.9, ALSA_0.9.0rc4);
8208 OBSOLETE1(snd_pcm_hw_params_set_rate_first, ALSA_0.9, ALSA_0.9.0rc4);
8209 OBSOLETE1(snd_pcm_hw_params_set_rate_last, ALSA_0.9, ALSA_0.9.0rc4);
8210 
8211 OBSOLETE1(snd_pcm_hw_params_get_period_time, ALSA_0.9, ALSA_0.9.0rc4);
8212 OBSOLETE1(snd_pcm_hw_params_get_period_time_min, ALSA_0.9, ALSA_0.9.0rc4);
8213 OBSOLETE1(snd_pcm_hw_params_get_period_time_max, ALSA_0.9, ALSA_0.9.0rc4);
8214 OBSOLETE1(snd_pcm_hw_params_set_period_time_near, ALSA_0.9, ALSA_0.9.0rc4);
8215 OBSOLETE1(snd_pcm_hw_params_set_period_time_first, ALSA_0.9, ALSA_0.9.0rc4);
8216 OBSOLETE1(snd_pcm_hw_params_set_period_time_last, ALSA_0.9, ALSA_0.9.0rc4);
8217 
8218 OBSOLETE1(snd_pcm_hw_params_get_period_size, ALSA_0.9, ALSA_0.9.0rc4);
8219 OBSOLETE1(snd_pcm_hw_params_get_period_size_min, ALSA_0.9, ALSA_0.9.0rc4);
8220 OBSOLETE1(snd_pcm_hw_params_get_period_size_max, ALSA_0.9, ALSA_0.9.0rc4);
8221 OBSOLETE1(snd_pcm_hw_params_set_period_size_near, ALSA_0.9, ALSA_0.9.0rc4);
8222 OBSOLETE1(snd_pcm_hw_params_set_period_size_first, ALSA_0.9, ALSA_0.9.0rc4);
8223 OBSOLETE1(snd_pcm_hw_params_set_period_size_last, ALSA_0.9, ALSA_0.9.0rc4);
8224 
8225 OBSOLETE1(snd_pcm_hw_params_get_periods, ALSA_0.9, ALSA_0.9.0rc4);
8226 OBSOLETE1(snd_pcm_hw_params_get_periods_min, ALSA_0.9, ALSA_0.9.0rc4);
8227 OBSOLETE1(snd_pcm_hw_params_get_periods_max, ALSA_0.9, ALSA_0.9.0rc4);
8228 OBSOLETE1(snd_pcm_hw_params_set_periods_near, ALSA_0.9, ALSA_0.9.0rc4);
8229 OBSOLETE1(snd_pcm_hw_params_set_periods_first, ALSA_0.9, ALSA_0.9.0rc4);
8230 OBSOLETE1(snd_pcm_hw_params_set_periods_last, ALSA_0.9, ALSA_0.9.0rc4);
8231 
8232 OBSOLETE1(snd_pcm_hw_params_get_buffer_time, ALSA_0.9, ALSA_0.9.0rc4);
8233 OBSOLETE1(snd_pcm_hw_params_get_buffer_time_min, ALSA_0.9, ALSA_0.9.0rc4);
8234 OBSOLETE1(snd_pcm_hw_params_get_buffer_time_max, ALSA_0.9, ALSA_0.9.0rc4);
8235 OBSOLETE1(snd_pcm_hw_params_set_buffer_time_near, ALSA_0.9, ALSA_0.9.0rc4);
8236 OBSOLETE1(snd_pcm_hw_params_set_buffer_time_first, ALSA_0.9, ALSA_0.9.0rc4);
8237 OBSOLETE1(snd_pcm_hw_params_set_buffer_time_last, ALSA_0.9, ALSA_0.9.0rc4);
8238 
8239 OBSOLETE1(snd_pcm_hw_params_get_buffer_size, ALSA_0.9, ALSA_0.9.0rc4);
8240 OBSOLETE1(snd_pcm_hw_params_get_buffer_size_min, ALSA_0.9, ALSA_0.9.0rc4);
8241 OBSOLETE1(snd_pcm_hw_params_get_buffer_size_max, ALSA_0.9, ALSA_0.9.0rc4);
8242 OBSOLETE1(snd_pcm_hw_params_set_buffer_size_near, ALSA_0.9, ALSA_0.9.0rc4);
8243 OBSOLETE1(snd_pcm_hw_params_set_buffer_size_first, ALSA_0.9, ALSA_0.9.0rc4);
8244 OBSOLETE1(snd_pcm_hw_params_set_buffer_size_last, ALSA_0.9, ALSA_0.9.0rc4);
8245 
8246 OBSOLETE1(snd_pcm_hw_params_get_tick_time, ALSA_0.9, ALSA_0.9.0rc4);
8247 OBSOLETE1(snd_pcm_hw_params_get_tick_time_min, ALSA_0.9, ALSA_0.9.0rc4);
8248 OBSOLETE1(snd_pcm_hw_params_get_tick_time_max, ALSA_0.9, ALSA_0.9.0rc4);
8249 OBSOLETE1(snd_pcm_hw_params_set_tick_time_near, ALSA_0.9, ALSA_0.9.0rc4);
8250 OBSOLETE1(snd_pcm_hw_params_set_tick_time_first, ALSA_0.9, ALSA_0.9.0rc4);
8251 OBSOLETE1(snd_pcm_hw_params_set_tick_time_last, ALSA_0.9, ALSA_0.9.0rc4);
8252 
8253 OBSOLETE1(snd_pcm_sw_params_get_tstamp_mode, ALSA_0.9, ALSA_0.9.0rc4);
8254 OBSOLETE1(snd_pcm_sw_params_get_sleep_min, ALSA_0.9, ALSA_0.9.0rc4);
8255 OBSOLETE1(snd_pcm_sw_params_get_avail_min, ALSA_0.9, ALSA_0.9.0rc4);
8256 OBSOLETE1(snd_pcm_sw_params_get_xfer_align, ALSA_0.9, ALSA_0.9.0rc4);
8257 OBSOLETE1(snd_pcm_sw_params_get_start_threshold, ALSA_0.9, ALSA_0.9.0rc4);
8258 OBSOLETE1(snd_pcm_sw_params_get_stop_threshold, ALSA_0.9, ALSA_0.9.0rc4);
8259 OBSOLETE1(snd_pcm_sw_params_get_silence_threshold, ALSA_0.9, ALSA_0.9.0rc4);
8260 OBSOLETE1(snd_pcm_sw_params_get_silence_size, ALSA_0.9, ALSA_0.9.0rc4);
8261 
8262 #endif /* DOC_HIDDEN */
8263 
chmap_equal(const snd_pcm_chmap_t *a, const snd_pcm_chmap_t *b)8264 static int chmap_equal(const snd_pcm_chmap_t *a, const snd_pcm_chmap_t *b)
8265 {
8266 	if (a->channels != b->channels)
8267 		return 0;
8268 	return !memcmp(a->pos, b->pos, a->channels * sizeof(a->pos[0]));
8269 }
8270 
8271 /**
8272  * \!brief Query the available channel maps
8273  * \param pcm PCM handle to query
8274  * \return the NULL-terminated array of integer pointers, each of
8275  * which contains the channel map. A channel map is represented by an
8276  * integer array, beginning with the channel map type, followed by the
8277  * number of channels, and the position of each channel. Return NULL
8278  * in case of an error.
8279  *
8280  * Note: the caller is requested to release the returned value via
8281  * snd_pcm_free_chmaps().
8282  */
snd_pcm_query_chmaps(snd_pcm_t *pcm)8283 snd_pcm_chmap_query_t **snd_pcm_query_chmaps(snd_pcm_t *pcm)
8284 {
8285 	if (!pcm->ops->query_chmaps)
8286 		return NULL;
8287 	return pcm->ops->query_chmaps(pcm);
8288 }
8289 
8290 /**
8291  * \!brief Release the channel map array allocated via #snd_pcm_query_chmaps
8292  * \param maps the array pointer to release
8293  */
snd_pcm_free_chmaps(snd_pcm_chmap_query_t **maps)8294 void snd_pcm_free_chmaps(snd_pcm_chmap_query_t **maps)
8295 {
8296 	snd_pcm_chmap_query_t **p;
8297 	if (!maps)
8298 		return;
8299 	for (p = maps; *p; p++)
8300 		free(*p);
8301 	free(maps);
8302 }
8303 
8304 /**
8305  * \!brief Get the current channel map
8306  * \param pcm PCM instance
8307  * \return the current channel map, or NULL if error
8308  *
8309  * Note: the caller is requested to release the returned value via free()
8310  */
snd_pcm_get_chmap(snd_pcm_t *pcm)8311 snd_pcm_chmap_t *snd_pcm_get_chmap(snd_pcm_t *pcm)
8312 {
8313 	if (!pcm->ops->get_chmap)
8314 		return NULL;
8315 	return pcm->ops->get_chmap(pcm);
8316 }
8317 
8318 /**
8319  * \!brief Configure the current channel map
8320  * \param pcm PCM instance
8321  * \param map the channel map to write
8322  * \return zero if succeeded, or a negative error code
8323  */
snd_pcm_set_chmap(snd_pcm_t *pcm, const snd_pcm_chmap_t *map)8324 int snd_pcm_set_chmap(snd_pcm_t *pcm, const snd_pcm_chmap_t *map)
8325 {
8326 	const snd_pcm_chmap_t *oldmap;
8327 	int nochange;
8328 
8329 	oldmap = snd_pcm_get_chmap(pcm);
8330 	nochange = (oldmap && chmap_equal(oldmap, map));
8331 	free((void *)oldmap);
8332 	if (nochange)
8333 		return 0;
8334 
8335 	if (!pcm->ops->set_chmap)
8336 		return -ENXIO;
8337 	return pcm->ops->set_chmap(pcm, map);
8338 }
8339 
8340 /*
8341  */
8342 #ifndef DOC_HIDDEN
8343 #define _NAME(n) [SND_CHMAP_TYPE_##n] = #n
8344 static const char *chmap_type_names[SND_CHMAP_TYPE_LAST + 1] = {
8345 	_NAME(NONE), _NAME(FIXED), _NAME(VAR), _NAME(PAIRED),
8346 };
8347 #undef _NAME
8348 #endif
8349 
8350 /**
8351  * \!brief Get a name string for a channel map type as query results
8352  * \param val Channel position
8353  * \return The string corresponding to the given type, or NULL
8354  */
snd_pcm_chmap_type_name(enum snd_pcm_chmap_type val)8355 const char *snd_pcm_chmap_type_name(enum snd_pcm_chmap_type val)
8356 {
8357 	if (val <= SND_CHMAP_TYPE_LAST)
8358 		return chmap_type_names[val];
8359 	else
8360 		return NULL;
8361 }
8362 
8363 #ifndef DOC_HIDDEN
8364 #define _NAME(n) [SND_CHMAP_##n] = #n
8365 static const char *chmap_names[SND_CHMAP_LAST + 1] = {
8366 	_NAME(UNKNOWN), _NAME(NA), _NAME(MONO),
8367 	_NAME(FL), _NAME(FR),
8368 	_NAME(RL), _NAME(RR),
8369 	_NAME(FC), _NAME(LFE),
8370 	_NAME(SL), _NAME(SR),
8371 	_NAME(RC), _NAME(FLC), _NAME(FRC), _NAME(RLC), _NAME(RRC),
8372 	_NAME(FLW), _NAME(FRW),
8373 	_NAME(FLH), _NAME(FCH), _NAME(FRH), _NAME(TC),
8374 	_NAME(TFL), _NAME(TFR), _NAME(TFC),
8375 	_NAME(TRL), _NAME(TRR), _NAME(TRC),
8376 	_NAME(TFLC), _NAME(TFRC), _NAME(TSL), _NAME(TSR),
8377 	_NAME(LLFE), _NAME(RLFE),
8378 	_NAME(BC), _NAME(BLC), _NAME(BRC),
8379 };
8380 #undef _NAME
8381 #endif
8382 
8383 /**
8384  * \!brief Get a name string for a standard channel map position
8385  * \param val Channel position
8386  * \return The string corresponding to the given position, or NULL
8387  */
snd_pcm_chmap_name(enum snd_pcm_chmap_position val)8388 const char *snd_pcm_chmap_name(enum snd_pcm_chmap_position val)
8389 {
8390 	if (val <= SND_CHMAP_LAST)
8391 		return chmap_names[val];
8392 	else
8393 		return NULL;
8394 }
8395 
8396 static const char *chmap_long_names[SND_CHMAP_LAST + 1] = {
8397 	[SND_CHMAP_UNKNOWN] = "Unknown",
8398 	[SND_CHMAP_NA] = "Unused",
8399 	[SND_CHMAP_MONO] = "Mono",
8400 	[SND_CHMAP_FL] = "Front Left",
8401 	[SND_CHMAP_FR] = "Front Right",
8402 	[SND_CHMAP_RL] = "Rear Left",
8403 	[SND_CHMAP_RR] = "Rear Right",
8404 	[SND_CHMAP_FC] = "Front Center",
8405 	[SND_CHMAP_LFE] = "LFE",
8406 	[SND_CHMAP_SL] = "Side Left",
8407 	[SND_CHMAP_SR] = "Side Right",
8408 	[SND_CHMAP_RC] = "Rear Center",
8409 	[SND_CHMAP_FLC] = "Front Left Center",
8410 	[SND_CHMAP_FRC] = "Front Right Center",
8411 	[SND_CHMAP_RLC] = "Rear Left Center",
8412 	[SND_CHMAP_RRC] = "Rear Right Center",
8413 	[SND_CHMAP_FLW] = "Front Left Wide",
8414 	[SND_CHMAP_FRW] = "Front Right Wide",
8415 	[SND_CHMAP_FLH] = "Front Left High",
8416 	[SND_CHMAP_FCH] = "Front Center High",
8417 	[SND_CHMAP_FRH] = "Front Right High",
8418 	[SND_CHMAP_TC] = "Top Center",
8419 	[SND_CHMAP_TFL] = "Top Front Left",
8420 	[SND_CHMAP_TFR] = "Top Front Right",
8421 	[SND_CHMAP_TFC] = "Top Front Center",
8422 	[SND_CHMAP_TRL] = "Top Rear Left",
8423 	[SND_CHMAP_TRR] = "Top Rear Right",
8424 	[SND_CHMAP_TRC] = "Top Rear Center",
8425 	[SND_CHMAP_TFLC] = "Top Front Left Center",
8426 	[SND_CHMAP_TFRC] = "Top Front Right Center",
8427 	[SND_CHMAP_TSL] = "Top Side Left",
8428 	[SND_CHMAP_TSR] = "Top Side Right",
8429 	[SND_CHMAP_LLFE] = "Left LFE",
8430 	[SND_CHMAP_RLFE] = "Right LFE",
8431 	[SND_CHMAP_BC] = "Bottom Center",
8432 	[SND_CHMAP_BLC] = "Bottom Left Center",
8433 	[SND_CHMAP_BRC] = "Bottom Right Center",
8434 };
8435 
8436 /**
8437  * \!brief Get a longer name string for a standard channel map position
8438  * \param val Channel position
8439  * \return The string corresponding to the given position, or NULL
8440  */
snd_pcm_chmap_long_name(enum snd_pcm_chmap_position val)8441 const char *snd_pcm_chmap_long_name(enum snd_pcm_chmap_position val)
8442 {
8443 	if (val <= SND_CHMAP_LAST)
8444 		return chmap_long_names[val];
8445 	else
8446 		return NULL;
8447 }
8448 
8449 /**
8450  * \!brief Print the channels in chmap on the buffer
8451  * \param map The channel map to print
8452  * \param maxlen The maximal length to write (including NUL letter)
8453  * \param buf The buffer to write
8454  * \return The actual string length or a negative error code
8455  */
snd_pcm_chmap_print(const snd_pcm_chmap_t *map, size_t maxlen, char *buf)8456 int snd_pcm_chmap_print(const snd_pcm_chmap_t *map, size_t maxlen, char *buf)
8457 {
8458 	unsigned int i, len = 0;
8459 
8460 	for (i = 0; i < map->channels; i++) {
8461 		unsigned int p = map->pos[i] & SND_CHMAP_POSITION_MASK;
8462 		if (i > 0) {
8463 			len += snprintf(buf + len, maxlen - len, " ");
8464 			if (len >= maxlen)
8465 				return -ENOMEM;
8466 		}
8467 		if (map->pos[i] & SND_CHMAP_DRIVER_SPEC)
8468 			len += snprintf(buf + len, maxlen - len, "%d", p);
8469 		else {
8470 			const char *name = chmap_names[p];
8471 			if (name)
8472 				len += snprintf(buf + len, maxlen - len,
8473 						"%s", name);
8474 			else
8475 				len += snprintf(buf + len, maxlen - len,
8476 						"Ch%d", p);
8477 		}
8478 		if (len >= maxlen)
8479 			return -ENOMEM;
8480 		if (map->pos[i] & SND_CHMAP_PHASE_INVERSE) {
8481 			len += snprintf(buf + len, maxlen - len, "[INV]");
8482 			if (len >= maxlen)
8483 				return -ENOMEM;
8484 		}
8485 	}
8486 	return len;
8487 }
8488 
str_to_chmap(const char *str, int len)8489 static int str_to_chmap(const char *str, int len)
8490 {
8491 	int val;
8492 	unsigned long v;
8493 	char *p;
8494 
8495 	if (isdigit(*str)) {
8496 		v = strtoul(str, &p, 0);
8497 		if (v == ULONG_MAX)
8498 			return -1;
8499 		val = v;
8500 		val |= SND_CHMAP_DRIVER_SPEC;
8501 		str = p;
8502 	} else if (!strncasecmp(str, "ch", 2)) {
8503 		v = strtoul(str + 2, &p, 0);
8504 		if (v == ULONG_MAX)
8505 			return -1;
8506 		val = v;
8507 		str = p;
8508 	} else {
8509 		for (val = 0; val <= SND_CHMAP_LAST; val++) {
8510 			int slen;
8511 			assert(chmap_names[val]);
8512 			slen = strlen(chmap_names[val]);
8513 			if (slen > len)
8514 				continue;
8515 			if (!strncasecmp(str, chmap_names[val], slen) &&
8516 			    !isalpha(str[slen])) {
8517 				str += slen;
8518 				break;
8519 			}
8520 		}
8521 		if (val > SND_CHMAP_LAST)
8522 			return -1;
8523 	}
8524 	if (str && !strncasecmp(str, "[INV]", 5))
8525 		val |= SND_CHMAP_PHASE_INVERSE;
8526 	return val;
8527 }
8528 
8529 /**
8530  * \!brief Convert from string to channel position
8531  * \param str The string to parse
8532  * \return The channel position value or -1 as an error
8533  */
snd_pcm_chmap_from_string(const char *str)8534 unsigned int snd_pcm_chmap_from_string(const char *str)
8535 {
8536 	return str_to_chmap(str, strlen(str));
8537 }
8538 
8539 /**
8540  * \!brief Convert from string to channel map
8541  * \param str The string to parse
8542  * \return The channel map
8543  *
8544  * Note: the caller is requested to release the returned value via free()
8545  */
snd_pcm_chmap_parse_string(const char *str)8546 snd_pcm_chmap_t *snd_pcm_chmap_parse_string(const char *str)
8547 {
8548 	int i, ch = 0;
8549 	int tmp_map[64];
8550 	snd_pcm_chmap_t *map;
8551 
8552 	for (;;) {
8553 		const char *p;
8554 		int len, val;
8555 
8556 		if (ch >= (int)(sizeof(tmp_map) / sizeof(tmp_map[0])))
8557 			return NULL;
8558 		for (p = str; *p && isalnum(*p); p++)
8559 			;
8560 		len = p - str;
8561 		if (!len)
8562 			return NULL;
8563 		val = str_to_chmap(str, len);
8564 		if (val < 0)
8565 			return NULL;
8566 		str += len;
8567 		if (*str == '[') {
8568 			if (!strncmp(str, "[INV]", 5)) {
8569 				val |= SND_CHMAP_PHASE_INVERSE;
8570 				str += 5;
8571 			}
8572 		}
8573 		tmp_map[ch] = val;
8574 		ch++;
8575 		for (; *str && !isalnum(*str); str++)
8576 			;
8577 		if (!*str)
8578 			break;
8579 	}
8580 	map = malloc(sizeof(*map) + ch * sizeof(int));
8581 	if (!map)
8582 		return NULL;
8583 	map->channels = ch;
8584 	for (i = 0; i < ch; i++)
8585 		map->pos[i] = tmp_map[i];
8586 	return map;
8587 }
8588 
8589 /* copy a single channel map with the fixed type to chmap_query pointer */
_copy_to_fixed_query_map(snd_pcm_chmap_query_t **dst, const snd_pcm_chmap_t *src)8590 static int _copy_to_fixed_query_map(snd_pcm_chmap_query_t **dst,
8591 				    const snd_pcm_chmap_t *src)
8592 {
8593 	*dst = malloc((src->channels + 2) * sizeof(int));
8594 	if (!*dst)
8595 		return -ENOMEM;
8596 	(*dst)->type = SND_CHMAP_TYPE_FIXED;
8597 	memcpy(&(*dst)->map, src, (src->channels + 1) * sizeof(int));
8598 	return 0;
8599 }
8600 
8601 #ifndef DOC_HIDDEN
8602 /* make a chmap_query array from a single channel map */
8603 snd_pcm_chmap_query_t **
_snd_pcm_make_single_query_chmaps(const snd_pcm_chmap_t *src)8604 _snd_pcm_make_single_query_chmaps(const snd_pcm_chmap_t *src)
8605 {
8606 	snd_pcm_chmap_query_t **maps;
8607 
8608 	maps = calloc(2, sizeof(*maps));
8609 	if (!maps)
8610 		return NULL;
8611 	if (_copy_to_fixed_query_map(maps, src)) {
8612 		free(maps);
8613 		return NULL;
8614 	}
8615 	return maps;
8616 }
8617 
8618 /* make a copy of chmap */
_snd_pcm_copy_chmap(const snd_pcm_chmap_t *src)8619 snd_pcm_chmap_t *_snd_pcm_copy_chmap(const snd_pcm_chmap_t *src)
8620 {
8621 	snd_pcm_chmap_t *map;
8622 
8623 	map = malloc((src->channels + 1) * sizeof(int));
8624 	if (!map)
8625 		return NULL;
8626 	memcpy(map, src, (src->channels + 1) * sizeof(int));
8627 	return map;
8628 }
8629 
8630 /* make a copy of channel maps */
8631 snd_pcm_chmap_query_t **
_snd_pcm_copy_chmap_query(snd_pcm_chmap_query_t * const *src)8632 _snd_pcm_copy_chmap_query(snd_pcm_chmap_query_t * const *src)
8633 {
8634 	snd_pcm_chmap_query_t * const *p;
8635 	snd_pcm_chmap_query_t **maps;
8636 	int i, nums;
8637 
8638 	for (nums = 0, p = src; *p; p++)
8639 		nums++;
8640 
8641 	maps = calloc(nums + 1, sizeof(*maps));
8642 	if (!maps)
8643 		return NULL;
8644 	for (i = 0; i < nums; i++) {
8645 		maps[i] = malloc((src[i]->map.channels + 2) * sizeof(int));
8646 		if (!maps[i]) {
8647 			snd_pcm_free_chmaps(maps);
8648 			return NULL;
8649 		}
8650 		memcpy(maps[i], src[i], (src[i]->map.channels + 2) * sizeof(int));
8651 	}
8652 	return maps;
8653 }
8654 
8655 /* select the channel map with the current PCM channels and make a copy */
8656 snd_pcm_chmap_t *
_snd_pcm_choose_fixed_chmap(snd_pcm_t *pcm, snd_pcm_chmap_query_t * const *maps)8657 _snd_pcm_choose_fixed_chmap(snd_pcm_t *pcm, snd_pcm_chmap_query_t * const *maps)
8658 {
8659 	snd_pcm_chmap_query_t * const *p;
8660 
8661 	for (p = maps; *p; p++) {
8662 		if ((*p)->map.channels == pcm->channels)
8663 			return _snd_pcm_copy_chmap(&(*p)->map);
8664 	}
8665 	return NULL;
8666 }
8667 
8668 /* make chmap_query array from the config tree;
8669  * conf must be a compound (array)
8670  */
8671 snd_pcm_chmap_query_t **
_snd_pcm_parse_config_chmaps(snd_config_t *conf)8672 _snd_pcm_parse_config_chmaps(snd_config_t *conf)
8673 {
8674 	snd_pcm_chmap_t *chmap;
8675 	snd_pcm_chmap_query_t **maps;
8676 	snd_config_iterator_t i, next;
8677 	const char *str;
8678 	int nums, err;
8679 
8680 	if (snd_config_get_type(conf) != SND_CONFIG_TYPE_COMPOUND)
8681 		return NULL;
8682 
8683 	nums = 0;
8684 	snd_config_for_each(i, next, conf) {
8685 		nums++;
8686 	}
8687 
8688 	maps = calloc(nums + 1, sizeof(*maps));
8689 	if (!maps)
8690 		return NULL;
8691 
8692 	nums = 0;
8693 	snd_config_for_each(i, next, conf) {
8694 		snd_config_t *n = snd_config_iterator_entry(i);
8695 		err = snd_config_get_string(n, &str);
8696 		if (err < 0)
8697 			goto error;
8698 		chmap = snd_pcm_chmap_parse_string(str);
8699 		if (!chmap)
8700 			goto error;
8701 		if (_copy_to_fixed_query_map(maps + nums, chmap)) {
8702 			free(chmap);
8703 			goto error;
8704 		}
8705 		free(chmap);
8706 		nums++;
8707 	}
8708 	return maps;
8709 
8710  error:
8711 	snd_pcm_free_chmaps(maps);
8712 	return NULL;
8713 }
8714 #endif /* DOC_HIDDEN */
8715 
8716 /*
8717  * basic helpers
8718  */
8719 
8720 
8721 /**
8722  * \brief Recover the stream state from an error or suspend
8723  * \param pcm PCM handle
8724  * \param err error number
8725  * \param silent do not print error reason
8726  * \return 0 when error code was handled successfuly, otherwise a negative error code
8727  *
8728  * This a high-level helper function building on other functions.
8729  *
8730  * This functions handles -EINTR (interrupted system call),
8731  * -EPIPE (overrun or underrun) and -ESTRPIPE (stream is suspended)
8732  * error codes trying to prepare given stream for next I/O.
8733  *
8734  * Note that this function returs the original error code when it is not
8735  * handled inside this function (for example -EAGAIN is returned back).
8736  */
snd_pcm_recover(snd_pcm_t *pcm, int err, int silent)8737 int snd_pcm_recover(snd_pcm_t *pcm, int err, int silent)
8738 {
8739         if (err > 0)
8740                 err = -err;
8741         if (err == -EINTR)	/* nothing to do, continue */
8742                 return 0;
8743         if (err == -EPIPE) {
8744                 const char *s;
8745                 if (snd_pcm_stream(pcm) == SND_PCM_STREAM_PLAYBACK)
8746                         s = "underrun";
8747                 else
8748                         s = "overrun";
8749                 if (!silent)
8750                         SNDERR("%s occurred", s);
8751                 err = snd_pcm_prepare(pcm);
8752                 if (err < 0) {
8753                         SNDERR("cannot recovery from %s, prepare failed: %s", s, snd_strerror(err));
8754                         return err;
8755                 }
8756                 return 0;
8757         }
8758         if (err == -ESTRPIPE) {
8759                 while ((err = snd_pcm_resume(pcm)) == -EAGAIN)
8760                         /* wait until suspend flag is released */
8761                         poll(NULL, 0, 1000);
8762                 if (err < 0) {
8763                         err = snd_pcm_prepare(pcm);
8764                         if (err < 0) {
8765                                 SNDERR("cannot recovery from suspend, prepare failed: %s", snd_strerror(err));
8766                                 return err;
8767                         }
8768                 }
8769                 return 0;
8770         }
8771         return err;
8772 }
8773 
8774 /**
8775  * \brief Set the hardware and software parameters in a simple way
8776  * \param pcm PCM handle
8777  * \param format required PCM format
8778  * \param access required PCM access
8779  * \param channels required PCM channels
8780  * \param rate required sample rate in Hz
8781  * \param soft_resample 0 = disallow alsa-lib resample stream, 1 = allow resampling
8782  * \param latency required overall latency in us
8783  * \return 0 on success otherwise a negative error code
8784  */
snd_pcm_set_params(snd_pcm_t *pcm, snd_pcm_format_t format, snd_pcm_access_t access, unsigned int channels, unsigned int rate, int soft_resample, unsigned int latency)8785 int snd_pcm_set_params(snd_pcm_t *pcm,
8786                        snd_pcm_format_t format,
8787                        snd_pcm_access_t access,
8788                        unsigned int channels,
8789                        unsigned int rate,
8790                        int soft_resample,
8791                        unsigned int latency)
8792 {
8793 	snd_pcm_hw_params_t params_saved, params = {0};
8794 	snd_pcm_sw_params_t swparams = {0};
8795 	const char *s = snd_pcm_stream_name(snd_pcm_stream(pcm));
8796 	snd_pcm_uframes_t buffer_size, period_size;
8797 	unsigned int rrate, period_time;
8798 	int err;
8799 
8800 	assert(pcm);
8801 	/* choose all parameters */
8802 	err = snd_pcm_hw_params_any(pcm, &params);
8803 	if (err < 0) {
8804 		SNDERR("Broken configuration for %s: no configurations available",
8805 		       s);
8806 		return err;
8807         }
8808 	/* set software resampling */
8809 	err = snd_pcm_hw_params_set_rate_resample(pcm, &params, soft_resample);
8810 	if (err < 0) {
8811 		SNDERR("Resampling setup failed for %s: %s",
8812 		       s, snd_strerror(err));
8813 		return err;
8814 	}
8815 	/* set the selected read/write format */
8816 	err = snd_pcm_hw_params_set_access(pcm, &params, access);
8817 	if (err < 0) {
8818 		SNDERR("Access type not available for %s: %s",
8819 		       s, snd_strerror(err));
8820 		return err;
8821 	}
8822 	/* set the sample format */
8823 	err = snd_pcm_hw_params_set_format(pcm, &params, format);
8824 	if (err < 0) {
8825 		SNDERR("Sample format not available for %s: %s",
8826 		       s, snd_strerror(err));
8827 		return err;
8828 	}
8829 	/* set the count of channels */
8830 	err = snd_pcm_hw_params_set_channels(pcm, &params, channels);
8831 	if (err < 0) {
8832 		SNDERR("Channels count (%i) not available for %s: %s",
8833 		       channels, s, snd_strerror(err));
8834 		return err;
8835 	}
8836 	/* set the stream rate */
8837 	rrate = rate;
8838 	err = INTERNAL(snd_pcm_hw_params_set_rate_near)(pcm, &params, &rrate,
8839 							0);
8840 	if (err < 0) {
8841 		SNDERR("Rate %iHz not available for playback: %s",
8842 		       rate, snd_strerror(err));
8843 		return err;
8844 	}
8845 	if (rrate != rate) {
8846 		SNDERR("Rate doesn't match (requested %iHz, get %iHz)",
8847 		       rate, rrate);
8848 		return -EINVAL;
8849 	}
8850 	/* set the buffer time */
8851 	params_saved = params;
8852 	err = INTERNAL(snd_pcm_hw_params_set_buffer_time_near)(pcm, &params,
8853 							&latency, NULL);
8854 	if (err < 0) {
8855 		/* error path -> set period size as first */
8856 		params = params_saved;
8857 		/* set the period time */
8858 		period_time = latency / 4;
8859 		err = INTERNAL(snd_pcm_hw_params_set_period_time_near)(pcm,
8860 						&params, &period_time, NULL);
8861 		if (err < 0) {
8862 			SNDERR("Unable to set period time %i for %s: %s",
8863 			       period_time, s, snd_strerror(err));
8864 			return err;
8865 		}
8866 		err = INTERNAL(snd_pcm_hw_params_get_period_size)(&params,
8867 							&period_size, NULL);
8868 		if (err < 0) {
8869 			SNDERR("Unable to get period size for %s: %s",
8870 							s, snd_strerror(err));
8871 			return err;
8872 		}
8873 		buffer_size = period_size * 4;
8874 		err = INTERNAL(snd_pcm_hw_params_set_buffer_size_near)(pcm,
8875 							&params, &buffer_size);
8876 		if (err < 0) {
8877 			SNDERR("Unable to set buffer size %lu %s: %s",
8878 					buffer_size, s, snd_strerror(err));
8879 			return err;
8880 		}
8881 		err = INTERNAL(snd_pcm_hw_params_get_buffer_size)(&params,
8882 								&buffer_size);
8883 		if (err < 0) {
8884 			SNDERR("Unable to get buffer size for %s: %s",
8885 			       s, snd_strerror(err));
8886 			return err;
8887 		}
8888 	} else {
8889 		/* standard configuration buffer_time -> periods */
8890 		err = INTERNAL(snd_pcm_hw_params_get_buffer_size)(&params,
8891 								&buffer_size);
8892 		if (err < 0) {
8893 			SNDERR("Unable to get buffer size for %s: %s",
8894 							s, snd_strerror(err));
8895 			return err;
8896 		}
8897 		err = INTERNAL(snd_pcm_hw_params_get_buffer_time)(&params,
8898 							&latency, NULL);
8899 		if (err < 0) {
8900 			SNDERR("Unable to get buffer time (latency) for %s: %s",
8901 			       s, snd_strerror(err));
8902 			return err;
8903 		}
8904 		/* set the period time */
8905 		period_time = latency / 4;
8906 		err = INTERNAL(snd_pcm_hw_params_set_period_time_near)(pcm,
8907 						&params, &period_time, NULL);
8908 		if (err < 0) {
8909 			SNDERR("Unable to set period time %i for %s: %s",
8910 			       period_time, s, snd_strerror(err));
8911 			return err;
8912 		}
8913 		err = INTERNAL(snd_pcm_hw_params_get_period_size)(&params,
8914 							&period_size, NULL);
8915 		if (err < 0) {
8916 			SNDERR("Unable to get period size for %s: %s",
8917 			       s, snd_strerror(err));
8918 			return err;
8919 		}
8920 	}
8921 	/* write the parameters to device */
8922 	err = snd_pcm_hw_params(pcm, &params);
8923 	if (err < 0) {
8924 		SNDERR("Unable to set hw params for %s: %s",
8925 		       s, snd_strerror(err));
8926 		return err;
8927 	}
8928 
8929 	/* get the current swparams */
8930 	err = snd_pcm_sw_params_current(pcm, &swparams);
8931 	if (err < 0) {
8932 		SNDERR("Unable to determine current swparams for %s: %s",
8933 		       s, snd_strerror(err));
8934 		return err;
8935 	}
8936 	/*
8937 	 * start the transfer when the buffer is almost full:
8938 	 * (buffer_size / avail_min) * avail_min
8939 	 */
8940 	err = snd_pcm_sw_params_set_start_threshold(pcm, &swparams,
8941 				(buffer_size / period_size) * period_size);
8942 	if (err < 0) {
8943 		SNDERR("Unable to set start threshold mode for %s: %s",
8944 		       s, snd_strerror(err));
8945 		return err;
8946 	}
8947 	/*
8948 	 * allow the transfer when at least period_size samples can be
8949 	 * processed
8950 	 */
8951 	err = snd_pcm_sw_params_set_avail_min(pcm, &swparams, period_size);
8952 	if (err < 0) {
8953 		SNDERR("Unable to set avail min for %s: %s",
8954 		       s, snd_strerror(err));
8955 		return err;
8956 	}
8957 	/* write the parameters to the playback device */
8958 	err = snd_pcm_sw_params(pcm, &swparams);
8959 	if (err < 0) {
8960 		SNDERR("Unable to set sw params for %s: %s",
8961 		       s, snd_strerror(err));
8962 		return err;
8963 	}
8964 	return 0;
8965 }
8966 
8967 /**
8968  * \brief Get the transfer size parameters in a simple way
8969  * \param pcm PCM handle
8970  * \param buffer_size PCM ring buffer size in frames
8971  * \param period_size PCM period size in frames
8972  * \return 0 on success otherwise a negative error code
8973  */
snd_pcm_get_params(snd_pcm_t *pcm, snd_pcm_uframes_t *buffer_size, snd_pcm_uframes_t *period_size)8974 int snd_pcm_get_params(snd_pcm_t *pcm,
8975                        snd_pcm_uframes_t *buffer_size,
8976                        snd_pcm_uframes_t *period_size)
8977 {
8978 	snd_pcm_hw_params_t params = {0};
8979 	int err;
8980 
8981 	assert(pcm);
8982 	err = snd_pcm_hw_params_current(pcm, &params);
8983 	if (err < 0)
8984 	        return err;
8985 	err = INTERNAL(snd_pcm_hw_params_get_buffer_size)(&params, buffer_size);
8986 	if (err < 0)
8987 		return err;
8988 	return INTERNAL(snd_pcm_hw_params_get_period_size)(&params, period_size,
8989 							   NULL);
8990 }
8991