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