OSDN Git Service

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