OSDN Git Service

Replaced snd_pcm_avail() with snd_pcm_hwsync()
[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@suse.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@suse.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., 59 Temple Place, Suite 330, Boston, MA  02111-1307 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. The select function is old and deprecated in modern
108 applications, so the ALSA library does not support it. The implemented
109 transfer routines can be found in the \ref alsa_transfers section.
110
111 \subsection pcm_transfer_async Asynchronous notification
112
113 ALSA driver and library knows to handle the asynchronous notifications over
114 the SIGIO signal. This signal allows to interrupt application and transfer
115 data in the signal handler. For further details see the sigaction function
116 ('man 2 sigaction'). The section \ref pcm_async describes the ALSA API for
117 this extension. The implemented transfer routines can be found in the
118 \ref alsa_transfers section.
119
120 \section pcm_open_behaviour Blocked and non-blocked open
121
122 The ALSA PCM API uses a different behaviour when the device is opened
123 with blocked or non-blocked mode. The mode can be specified with
124 \a mode argument in \link ::snd_pcm_open() \endlink function.
125 The blocked mode is the default (without \link ::SND_PCM_NONBLOCK \endlink mode).
126 In this mode, the behaviour is that if the resources have already used
127 with another application, then it blocks the caller, until resources are
128 free. The non-blocked behaviour (with \link ::SND_PCM_NONBLOCK \endlink)
129 doesn't block the caller in any way and returns -EBUSY error when the
130 resources are not available. Note that the mode also determines the
131 behaviour of standard I/O calls, returning -EAGAIN when non-blocked mode is
132 used and the ring buffer is full (playback) or empty (capture).
133 The operation mode for I/O calls can be changed later with
134 the \link snd_pcm_nonblock() \endlink function.
135
136 \section pcm_async Asynchronous mode
137
138 There is also possibility to receive asynchronous notification after
139 specified time periods. You may see the \link ::SND_PCM_ASYNC \endlink
140 mode for \link ::snd_pcm_open() \endlink function and
141 \link ::snd_async_add_pcm_handler() \endlink function for further details.
142
143 \section pcm_handshake Handshake between application and library
144
145 The ALSA PCM API design uses the states to determine the communication
146 phase between application and library. The actual state can be determined
147 using \link ::snd_pcm_state() \endlink call. There are these states:
148
149 \par SND_PCM_STATE_OPEN
150 The PCM device is in the open state. After the \link ::snd_pcm_open() \endlink open call,
151 the device is in this state. Also, when \link ::snd_pcm_hw_params() \endlink call fails,
152 then this state is entered to force application calling 
153 \link ::snd_pcm_hw_params() \endlink function to set right communication
154 parameters.
155
156 \par SND_PCM_STATE_SETUP
157 The PCM device has accepted communication parameters and it is waiting
158 for \link ::snd_pcm_prepare() \endlink call to prepare the hardware for
159 selected operation (playback or capture).
160
161 \par SND_PCM_STATE_PREPARE
162 The PCM device is prepared for operation. Application can use
163 \link ::snd_pcm_start() \endlink call, write or read data to start
164 the operation.
165
166 \par SND_PCM_STATE_RUNNING
167 The PCM device is running. It processes the samples. The stream can
168 be stopped using the \link ::snd_pcm_drop() \endlink or
169 \link ::snd_pcm_drain \endlink calls.
170
171 \par SND_PCM_STATE_XRUN
172 The PCM device reached overrun (capture) or underrun (playback).
173 You can use the -EPIPE return code from I/O functions
174 (\link ::snd_pcm_writei() \endlink, \link ::snd_pcm_writen() \endlink,
175  \link ::snd_pcm_readi() \endlink, \link ::snd_pcm_readi() \endlink)
176 to determine this state without checking
177 the actual state via \link ::snd_pcm_state() \endlink call. You can recover from
178 this state with \link ::snd_pcm_prepare() \endlink,
179 \link ::snd_pcm_drop() \endlink or \link ::snd_pcm_drain() \endlink calls.
180
181 \par SND_PCM_STATE_DRAINING
182 The device is in this state when application using the capture mode
183 called \link ::snd_pcm_drain() \endlink function. Until all data are
184 read from the internal ring buffer using I/O routines
185 (\link ::snd_pcm_readi() \endlink, \link ::snd_pcm_readn() \endlink),
186 then the device stays in this state.
187
188 \par SND_PCM_STATE_PAUSED
189 The device is in this state when application called
190 the \link ::snd_pcm_pause() \endlink function until the pause is released.
191 Not all hardware supports this feature. Application should check the
192 capability with the \link ::snd_pcm_hw_params_can_pause() \endlink.
193
194 \par SND_PCM_STATE_SUSPENDED
195 The device is in the suspend state provoked with the power management
196 system. The stream can be resumed using \link ::snd_pcm_resume() \endlink
197 call, but not all hardware supports this feature. Application should check
198 the capability with the \link ::snd_pcm_hw_params_can_resume() \endlink.
199 In other case, the calls \link ::snd_pcm_prepare() \endlink,
200 \link ::snd_pcm_drop() \endlink, \link ::snd_pcm_drain() \endlink can be used
201 to leave this state.
202
203 \section pcm_formats PCM formats
204
205 The full list of formats present the \link ::snd_pcm_format_t \endlink type.
206 The 24-bit linear samples uses 32-bit physical space, but the sample is
207 stored in low three bits. Some hardware does not support processing of full
208 range, thus you may get the significant bits for linear samples via
209 \link ::snd_pcm_hw_params_get_sbits \endlink function. The example: ICE1712
210 chips support 32-bit sample processing, but low byte is ignored (playback)
211 or zero (capture). The function \link ::snd_pcm_hw_params_get_sbits() \endlink
212 returns 24 in the case.
213
214 \section alsa_transfers ALSA transfers
215
216 There are two methods to transfer samples in application. The first method
217 is the standard read / write one. The second method, uses the direct audio
218 buffer to communicate with the device while ALSA library manages this space
219 itself. You can find examples of all communication schemes for playback
220 in \ref example_test_pcm "Sine-wave generator example". To complete the
221 list, we should note that \link ::snd_pcm_wait \endlink function contains
222 embedded poll waiting implementation.
223
224 \subsection alsa_pcm_rw Read / Write transfer
225
226 There are two versions of read / write routines. The first expects the
227 interleaved samples at input (#SND_PCM_ACCESS_RW_INTERLEAVED access method),
228 and the second one expects non-interleaved (samples in separated buffers -
229 #SND_PCM_ACCESS_RW_NONINTERLEAVED access method) at input. There are these
230 functions for interleaved transfers: \link ::snd_pcm_writei \endlink,
231 \link ::snd_pcm_readi \endlink. For non-interleaved transfers, there are
232 these functions: \link ::snd_pcm_writen \endlink and \link ::snd_pcm_readn
233 \endlink.
234
235 \subsection alsa_mmap_rw Direct Read / Write transfer (via mmap'ed areas)
236
237 Three kinds of organization of ring buffer memory areas exist in ALSA API.
238 Access #SND_PCM_ACCESS_MMAP_INTERLEAVED has interleaved samples. Access
239 #SND_PCM_ACCESS_MMAP_NONINTERLEAVED expects continous sample areas for
240 one channel. Access #SND_PCM_ACCESS_MMAP_COMPLEX does not fit to interleaved
241 and non-interleaved ring buffer organization.
242 \par
243
244 There are two functions for this kind of transfer. Application can get an
245 access to memory areas via \link ::snd_pcm_mmap_begin \endlink function.
246 This function returns the areas (single area is equal to a channel)
247 containing the direct pointers to memory and sample position description
248 in \link ::snd_pcm_channel_area_t \endlink structure. After application
249 transfers the data in the memory areas, then it must be acknowledged
250 the end of transfer via \link ::snd_pcm_mmap_commit() \endlink function
251 to allow the ALSA library update the pointers to ring buffer. This kind of
252 communication is also called "zero-copy", because the device does not require
253 to copy the samples from application to another place in system memory.
254 \par
255
256 If you like to use the compatibility functions in mmap mode, there are
257 read / write routines equaling to standard read / write transfers. Using
258 these functions discards the benefits of direct access to memory region.
259 See the \link ::snd_pcm_mmap_readi() \endlink,
260 \link ::snd_pcm_writei() \endlink, \link ::snd_pcm_readn() \endlink
261 and \link ::snd_pcm_writen() \endlink functions.
262
263 \section pcm_params Managing parameters
264
265 The ALSA PCM device uses two groups of PCM related parameters. The hardware
266 parameters contains the stream description like format, rate, count of
267 channels, ring buffer size etc. The software parameters contains the
268 software (driver) related parameters. The communication behaviour can be
269 controlled via these parameters, like automatic start, automatic stop,
270 interrupting (chunk acknowledge) etc. The software parameters can be
271 modified at any time (when valid hardware parameters are set). It includes
272 the running state as well.
273
274 \subsection pcm_hw_params Hardware related parameters
275
276 The ALSA PCM devices use the parameter refining system for hardware
277 parameters - \link ::snd_pcm_hw_params_t \endlink. It means, that
278 application choose the full-range of configurations at first and then
279 application sets single parameters until all parameters are elementary
280 (definite).
281
282 \par Access modes
283
284 ALSA knows about five access modes. The first three can be used for direct
285 communication. The access mode \link ::SND_PCM_ACCESS_MMAP_INTERLEAVED \endlink
286 determines the direct memory area and interleaved sample organization.
287 Interleaved organization means, that samples from channels are mixed together.
288 The access mode \link ::SND_PCM_ACCESS_MMAP_NONINTERLEAVED \endlink
289 determines the direct memory area and non-interleaved sample organization.
290 Each channel has a separate buffer in the case. The complex direct memory
291 organization represents the \link ::SND_PCM_ACCESS_MMAP_COMPLEX \endlink
292 access mode. The sample organization does not fit the interleaved or
293 non-interleaved access modes in the case. The last two access modes
294 describes the read / write access methods.
295 The \link ::SND_PCM_ACCESS_RW_INTERLEAVED \endlink access represents the read /
296 write interleaved access and the \link ::SND_PCM_ACCESS_RW_NONINTERLEAVED \endlink
297 represents the non-interleaved access.
298
299 \par Formats
300
301 The full list of formats is available in \link ::snd_pcm_format_t \endlink
302 enumeration.
303
304 \subsection pcm_sw_params Software related parameters
305
306 These parameters - \link ::snd_pcm_sw_params_t \endlink can be modified at
307 any time including the running state.
308
309 \par Minimum available count of samples
310
311 This parameter controls the wakeup point. If the count of available samples
312 is equal or greater than this value, then application will be activated.
313
314 \par Timestamp mode
315
316 The timestamp mode specifies, if timestamps are activated. Currently, only
317 \link ::SND_PCM_TSTAMP_NONE \endlink and \link ::SND_PCM_TSTAMP_MMAP
318 \endlink modes are known. The mmap mode means that timestamp is taken
319 on every period time boundary.
320
321 \par Minimal sleep
322
323 This parameters means the minimum of ticks to sleep using a standalone
324 timer (usually the system timer). The tick resolution can be obtained
325 via the function \link ::snd_pcm_hw_params_get_tick_time \endlink. This
326 function can be used to fine-tune the transfer acknowledge process. It could
327 be useful especially when some hardware does not support small transfer
328 periods.
329
330 \par Transfer align
331
332 The read / write transfers can be aligned to this sample count. The modulo
333 is ignored by device. Usually, this value is set to one (no align).
334
335 \par Start threshold
336
337 The start threshold parameter is used to determine the start point in
338 stream. For playback, if samples in ring buffer is equal or greater than
339 the start threshold parameters and the stream is not running, the stream will
340 be started automatically from the device. For capture, if the application wants
341 to read count of samples equal or greater then the stream will be started.
342 If you want to use explicit start (\link ::snd_pcm_start \endlink), you can
343 set this value greater than ring buffer size (in samples), but use the
344 constant MAXINT is not a bad idea.
345
346 \par Stop threshold
347
348 Similarly, the stop threshold parameter is used to automatically stop
349 the running stream, when the available samples crosses this boundary.
350 It means, for playback, the empty samples in ring buffer and for capture,
351 the filled (used) samples in ring buffer.
352
353 \par Silence threshold
354
355 The silence threshold specifies count of samples filled with silence
356 ahead of the current application pointer for playback. It is usable
357 for applications when an overrun is possible (like tasks depending on
358 network I/O etc.). If application wants to manage the ahead samples itself,
359 the \link ::snd_pcm_rewind() \endlink function allows to forget the last
360 samples in the stream.
361
362 \section pcm_status Obtaining stream status
363
364 The stream status is stored in \link ::snd_pcm_status_t \endlink structure.
365 These parameters can be obtained: the current stream state -
366 \link ::snd_pcm_status_get_state \endlink, timestamp of trigger -
367 \link ::snd_pcm_status_get_trigger_tstamp \endlink, timestamp of last
368 update \link ::snd_pcm_status_get_tstamp \endlink, delay in samples -
369 \link ::snd_pcm_status_get_delay \endlink, available count in samples -
370 \link ::snd_pcm_status_get_avail \endlink, maximum available samples -
371 \link ::snd_pcm_status_get_avail_max \endlink, ADC over-range count in
372 samples - \link ::snd_pcm_status_get_overrange \endlink. The last two
373 parameters - avail_max and overrange are reset to zero after the status
374 call.
375
376 \subsection pcm_status_fast Obtaining stream state fast and update r/w pointer
377
378 The function \link ::snd_pcm_avail_update \endlink updates the current
379 available count of samples for writing (playback) or filled samples for
380 reading (capture). This call is mandatory for updating actual r/w pointer.
381 Using standalone, it is a light method to obtain current stream position,
382 because it does not require the user <-> kernel context switch, but the value
383 is less accurate, because ring buffer pointers are updated in kernel drivers
384 only when an interrupt occurs. If you want to get accurate stream state,
385 use functions \link ::snd_pcm_avail \endlink or \link ::snd_pcm_delay \endlink.
386 Note that both of these functions do not update the current r/w pointer
387 for applications, so the function \link ::snd_pcm_avail_update \endlink must
388 be called afterwards before any read/write begin+commit operations.
389 <p>
390 The function \link ::snd_pcm_avail \endlink returns current available space
391 in the ring buffer. Note that this function does not update the current r/w
392 pointer for applications, so the function \link ::snd_pcm_avail_update \endlink
393 must be called afterwards before any read/write/begin+commit operations.
394 <p>
395 The function \link ::snd_pcm_delay \endlink returns the delay in samples.
396 For playback, it means count of samples in the ring buffer before
397 the next sample will be sent to DAC. For capture, it means count of samples
398 in the ring buffer before the next sample will be captured from ADC. It works
399 only when the stream is in the running or draining (playback only) state.
400 Note that this function does not update the current r/w pointer for applications,
401 so the function \link ::snd_pcm_avail_update \endlink must be called afterwards
402 before any read/write begin+commit operations.
403
404 \section pcm_action Managing the stream state
405
406 These functions directly and indirectly affecting the stream state:
407
408 \par snd_pcm_hw_params
409 The \link ::snd_pcm_hw_params \endlink function brings the stream state
410 to \link ::SND_PCM_STATE_SETUP \endlink
411 if successfully finishes, otherwise the state \link ::SND_PCM_STATE_OPEN
412 \endlink is entered.
413
414 \par snd_pcm_prepare
415 The \link ::snd_pcm_prepare \endlink function enters the
416 \link ::SND_PCM_STATE_PREPARED \endlink after a successful finish.
417
418 \par snd_pcm_start
419 The \link ::snd_pcm_start \endlink function enters
420 the \link ::SND_PCM_STATE_RUNNING \endlink after a successful finish.
421
422 \par snd_pcm_drop
423 The \link ::snd_pcm_drop \endlink function enters the
424 \link ::SND_PCM_STATE_SETUP \endlink state.
425
426 \par snd_pcm_drain
427 The \link ::snd_pcm_drain \endlink function enters the
428 \link ::SND_PCM_STATE_DRAINING \endlink, if
429 the capture device has some samples in the ring buffer otherwise
430 \link ::SND_PCM_STATE_SETUP \endlink state is entered.
431
432 \par snd_pcm_pause
433 The \link ::snd_pcm_pause \endlink function enters the
434 \link ::SND_PCM_STATE_PAUSED \endlink or
435 \link ::SND_PCM_STATE_RUNNING \endlink.
436
437 \par snd_pcm_writei, snd_pcm_writen
438 The \link ::snd_pcm_writei \endlink and \link ::snd_pcm_writen \endlink
439 functions can conditionally start the stream -
440 \link ::SND_PCM_STATE_RUNNING \endlink. They depend on the start threshold
441 software parameter.
442
443 \par snd_pcm_readi, snd_pcm_readn
444 The \link ::snd_pcm_readi \endlink and \link ::snd_pcm_readn \endlink
445 functions can conditionally start the stream -
446 \link ::SND_PCM_STATE_RUNNING \endlink. They depend on the start threshold
447 software parameter.
448
449 \section pcm_sync Streams synchronization
450
451 There are two functions allowing link multiple streams together. In the
452 case, the linking means that all operations are synchronized. Because the
453 drivers cannot guarantee the synchronization (sample resolution) on hardware
454 lacking this feature, the \link ::snd_pcm_info_get_sync \endlink function
455 returns synchronization ID - \link ::snd_pcm_sync_id_t \endlink, which is equal
456 for hardware synchronized streams. When the \link ::snd_pcm_link \endlink
457 function is called, all operations managing the stream state for these two
458 streams are joined. The opposite function is \link ::snd_pcm_unlink \endlink.
459
460 \section pcm_dev_names PCM naming conventions
461
462 The ALSA library uses a generic string representation for names of devices.
463 The devices might be virtual, physical or a mix of both. The generic string
464 is passed to \link ::snd_pcm_open() \endlink or \link ::snd_pcm_open_lconf() \endlink.
465 It contains two parts: device name and arguments. Devices and arguments are described
466 in configuration files. The usual place for default definitions is at /usr/share/alsa/alsa.conf.
467 For detailed descriptions about integrated PCM plugins look to \ref pcm_plugins.
468
469 \subsection pcm_dev_names_default Default device
470
471 The default device is equal to plug plugin with hw plugin as slave. The defaults are
472 used:
473
474 defaults.pcm.card 0
475 defaults.pcm.device 0
476 defaults.pcm.subdevice -1
477
478 These defaults can be freely overwritten in local configuration files.
479
480 Example:
481
482 \code
483 default
484 \endcode
485
486 \subsection pcm_dev_names_hw HW device
487
488 The hw device description uses the hw plugin. The three arguments (in order: CARD,DEV,SUBDEV)
489 specify card number or identifier, device number and subdevice number (-1 means any).
490
491 Example:
492
493 \code
494 hw
495 hw:0
496 hw:0,0
497 hw:supersonic,1
498 hw:soundwave,1,2
499 hw:DEV=1,CARD=soundwave,SUBDEV=2
500 \endcode
501
502 \subsection pcm_dev_names_plughw Plug->HW device
503
504 The plughw device description uses the plug plugin and hw plugin as slave. The arguments
505 are same as for hw device.
506
507 Example:
508
509 \code
510 plughw
511 plughw:0
512 plughw:0,0
513 plughw:supersonic,1
514 plughw:soundwave,1,2
515 plughw:DEV=1,CARD=soundwave,SUBDEV=2
516 \endcode
517
518 \subsection pcm_dev_names_plug Plug device
519
520 The plug device uses the plug plugin. The one SLAVE argument specifies the slave plugin.
521
522 Example:
523
524 \code
525 plug:mypcmdef
526 plug:hw
527 plug:'hw:0,0'
528 plug:SLAVE=hw
529 \endcode
530
531 \subsection pcm_dev_names_shm Shared memory device
532
533 The shm device uses the shm plugin. The two arguments (in order: SOCKET,PCM) specify
534 UNIX socket name (for example /tmp/alsa.socket) for server communication and server's PCM name.
535
536 Example:
537
538 \code
539 shm:'/tmp/alsa.sock',default
540 shm:SOCKET='/tmp/alsa.sock',PCM=default
541 \endcode
542
543 \subsection pcm_dev_names_tee Tee device
544
545 The tee device stores contents of a stream to given file plus transfers it to given slave plugin.
546 The three arguments (in order: SLAVE,FILE,FORMAT) specify slave plugin, filename and file format.
547
548 Example:
549
550 \code
551 tee:hw,'/tmp/out.raw',raw
552 \endcode
553
554 \subsection pcm_dev_names_file File device
555
556 The file device is file plugin with null plugin as slave. The arguments (in order: FILE,FORMAT)
557 specify filename and file format.
558
559 Example:
560
561 \code
562 file:'/tmp/out.raw',raw
563 \endcode
564
565 \subsection pcm_dev_names_null Null device
566
567 The null device is null plugin. This device has not any arguments.
568
569
570 \section pcm_examples Examples
571
572 The full featured examples with cross-links:
573
574 \par Sine-wave generator
575 \ref example_test_pcm "example code"
576 \par
577 This example shows various transfer methods for the playback direction.
578
579 \par Latency measuring tool
580 \ref example_test_latency "example code"
581 \par
582 This example shows the measuring of minimal latency between capture and
583 playback devices.
584
585 */
586
587 /**
588  * \example ../test/pcm.c
589  * \anchor example_test_pcm
590  */
591 /**
592  * \example ../test/latency.c
593  * \anchor example_test_latency
594  */
595
596
597 #include <stdio.h>
598 #include <string.h>
599 #include <malloc.h>
600 #include <stdarg.h>
601 #include <signal.h>
602 #include <dlfcn.h>
603 #include <sys/ioctl.h>
604 #include <sys/poll.h>
605 #include <sys/shm.h>
606 #include <sys/mman.h>
607 #include <limits.h>
608 #include "pcm_local.h"
609
610 /**
611  * \brief get identifier of PCM handle
612  * \param pcm PCM handle
613  * \return ascii identifier of PCM handle
614  *
615  * Returns the ASCII identifier of given PCM handle. It's the same
616  * identifier specified in snd_pcm_open().
617  */
618 const char *snd_pcm_name(snd_pcm_t *pcm)
619 {
620         assert(pcm);
621         return pcm->name;
622 }
623
624 /**
625  * \brief get type of PCM handle
626  * \param pcm PCM handle
627  * \return type of PCM handle
628  *
629  * Returns the type #snd_pcm_type_t of given PCM handle.
630  */
631 snd_pcm_type_t snd_pcm_type(snd_pcm_t *pcm)
632 {
633         assert(pcm);
634         return pcm->type;
635 }
636
637 /**
638  * \brief get stream for a PCM handle
639  * \param pcm PCM handle
640  * \return stream of PCM handle
641  *
642  * Returns the type #snd_pcm_stream_t of given PCM handle.
643  */
644 snd_pcm_stream_t snd_pcm_stream(snd_pcm_t *pcm)
645 {
646         assert(pcm);
647         return pcm->stream;
648 }
649
650 /**
651  * \brief close PCM handle
652  * \param pcm PCM handle
653  * \return 0 on success otherwise a negative error code
654  *
655  * Closes the specified PCM handle and frees all associated
656  * resources.
657  */
658 int snd_pcm_close(snd_pcm_t *pcm)
659 {
660         int err;
661         assert(pcm);
662         if (pcm->setup) {
663                 snd_pcm_drop(pcm);
664                 err = snd_pcm_hw_free(pcm);
665                 if (err < 0)
666                         return err;
667         }
668         while (!list_empty(&pcm->async_handlers)) {
669                 snd_async_handler_t *h = list_entry(pcm->async_handlers.next, snd_async_handler_t, hlist);
670                 snd_async_del_handler(h);
671         }
672         err = pcm->ops->close(pcm->op_arg);
673         if (err < 0)
674                 return err;
675         if (pcm->name)
676                 free(pcm->name);
677         if (pcm->hw.link_dst)
678                 free(pcm->hw.link_dst);
679         if (pcm->appl.link_dst)
680                 free(pcm->appl.link_dst);
681         free(pcm);
682         return 0;
683 }       
684
685 /**
686  * \brief set nonblock mode
687  * \param pcm PCM handle
688  * \param nonblock 0 = block, 1 = nonblock mode
689  * \return 0 on success otherwise a negative error code
690  */
691 int snd_pcm_nonblock(snd_pcm_t *pcm, int nonblock)
692 {
693         int err;
694         assert(pcm);
695         if ((err = pcm->ops->nonblock(pcm->op_arg, nonblock)) < 0)
696                 return err;
697         if (nonblock)
698                 pcm->mode |= SND_PCM_NONBLOCK;
699         else
700                 pcm->mode &= ~SND_PCM_NONBLOCK;
701         return 0;
702 }
703
704 #ifndef DOC_HIDDEN
705 /**
706  * \brief set async mode
707  * \param pcm PCM handle
708  * \param sig Signal to raise: < 0 disable, 0 default (SIGIO)
709  * \param pid Process ID to signal: 0 current
710  * \return 0 on success otherwise a negative error code
711  *
712  * A signal is raised every period.
713  */
714 int snd_pcm_async(snd_pcm_t *pcm, int sig, pid_t pid)
715 {
716         assert(pcm);
717         if (sig == 0)
718                 sig = SIGIO;
719         if (pid == 0)
720                 pid = getpid();
721         return pcm->ops->async(pcm->op_arg, sig, pid);
722 }
723 #endif
724
725 /**
726  * \brief Obtain general (static) information for PCM handle
727  * \param pcm PCM handle
728  * \param info Information container
729  * \return 0 on success otherwise a negative error code
730  */
731 int snd_pcm_info(snd_pcm_t *pcm, snd_pcm_info_t *info)
732 {
733         assert(pcm && info);
734         return pcm->ops->info(pcm->op_arg, info);
735 }
736
737 /** \brief Retreive current PCM hardware configuration chosen with #snd_pcm_hw_params
738  * \param pcm PCM handle
739  * \param params Configuration space definition container
740  * \return 0 on success otherwise a negative error code
741  */
742 int snd_pcm_hw_params_current(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
743 {
744         unsigned int frame_bits;
745
746         assert(pcm && params);
747         if (!pcm->setup)
748                 return -EBADFD;
749         snd_pcm_hw_params_clear(params);
750         snd_mask_copy(&params->masks[SND_PCM_HW_PARAM_ACCESS], (snd_mask_t *)&pcm->access);
751         snd_mask_copy(&params->masks[SND_PCM_HW_PARAM_FORMAT], (snd_mask_t *)&pcm->format);
752         snd_mask_copy(&params->masks[SND_PCM_HW_PARAM_SUBFORMAT], (snd_mask_t *)&pcm->subformat);
753         frame_bits = snd_pcm_format_physical_width(pcm->format) * pcm->channels;
754         snd_interval_set_value(&params->intervals[SND_PCM_HW_PARAM_FRAME_BITS], frame_bits);
755         snd_interval_set_value(&params->intervals[SND_PCM_HW_PARAM_CHANNELS], pcm->channels);
756         snd_interval_set_value(&params->intervals[SND_PCM_HW_PARAM_RATE], pcm->rate);
757         snd_interval_set_value(&params->intervals[SND_PCM_HW_PARAM_PERIOD_TIME], pcm->period_time);
758         snd_interval_set_value(&params->intervals[SND_PCM_HW_PARAM_PERIOD_SIZE], pcm->period_size);
759         snd_interval_copy(&params->intervals[SND_PCM_HW_PARAM_PERIODS], &pcm->periods);
760         snd_interval_copy(&params->intervals[SND_PCM_HW_PARAM_BUFFER_TIME], &pcm->buffer_time);
761         snd_interval_set_value(&params->intervals[SND_PCM_HW_PARAM_BUFFER_SIZE], pcm->buffer_size);
762         snd_interval_set_value(&params->intervals[SND_PCM_HW_PARAM_BUFFER_BYTES], (pcm->buffer_size * frame_bits) / 8);
763         snd_interval_set_value(&params->intervals[SND_PCM_HW_PARAM_TICK_TIME], pcm->tick_time);
764         params->info = pcm->info;
765         params->msbits = pcm->msbits;
766         params->rate_num = pcm->rate_num;
767         params->rate_den = pcm->rate_den;
768         params->fifo_size = pcm->fifo_size;
769         return 0;
770
771
772 /** \brief Install one PCM hardware configuration chosen from a configuration space and #snd_pcm_prepare it
773  * \param pcm PCM handle
774  * \param params Configuration space definition container
775  * \return 0 on success otherwise a negative error code
776  *
777  * The configuration is chosen fixing single parameters in this order:
778  * first access, first format, first subformat, min channels, min rate, 
779  * min period time, max buffer size, min tick time
780  */
781 int snd_pcm_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
782 {
783         int err;
784         assert(pcm && params);
785         err = _snd_pcm_hw_params(pcm, params);
786         if (err < 0)
787                 return err;
788         err = snd_pcm_prepare(pcm);
789         return err;
790 }
791
792 /** \brief Remove PCM hardware configuration and free associated resources
793  * \param pcm PCM handle
794  * \return 0 on success otherwise a negative error code
795  */
796 int snd_pcm_hw_free(snd_pcm_t *pcm)
797 {
798         int err;
799         assert(pcm->setup);
800         if (pcm->mmap_channels) {
801                 err = snd_pcm_munmap(pcm);
802                 if (err < 0)
803                         return err;
804         }
805         // assert(snd_pcm_state(pcm) == SND_PCM_STATE_SETUP ||
806         //        snd_pcm_state(pcm) == SND_PCM_STATE_PREPARED);
807         err = pcm->ops->hw_free(pcm->op_arg);
808         pcm->setup = 0;
809         if (err < 0)
810                 return err;
811         return 0;
812 }
813
814 /** \brief Install PCM software configuration defined by params
815  * \param pcm PCM handle
816  * \param params Configuration container
817  * \return 0 on success otherwise a negative error code
818  */
819 int snd_pcm_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t *params)
820 {
821         int err;
822         err = pcm->ops->sw_params(pcm->op_arg, params);
823         if (err < 0)
824                 return err;
825         pcm->tstamp_mode = snd_pcm_sw_params_get_tstamp_mode(params);
826         pcm->period_step = params->period_step;
827         pcm->sleep_min = params->sleep_min;
828         pcm->avail_min = params->avail_min;
829         pcm->xfer_align = params->xfer_align;
830         pcm->start_threshold = params->start_threshold;
831         pcm->stop_threshold = params->stop_threshold;
832         pcm->silence_threshold = params->silence_threshold;
833         pcm->silence_size = params->silence_size;
834         pcm->boundary = params->boundary;
835         return 0;
836 }
837
838 /**
839  * \brief Obtain status (runtime) information for PCM handle
840  * \param pcm PCM handle
841  * \param status Status container
842  * \return 0 on success otherwise a negative error code
843  */
844 int snd_pcm_status(snd_pcm_t *pcm, snd_pcm_status_t *status)
845 {
846         assert(pcm && status);
847         return pcm->fast_ops->status(pcm->fast_op_arg, status);
848 }
849
850 /**
851  * \brief Return PCM state
852  * \param pcm PCM handle
853  * \return PCM state #snd_pcm_state_t of given PCM handle
854  */
855 snd_pcm_state_t snd_pcm_state(snd_pcm_t *pcm)
856 {
857         assert(pcm);
858         return pcm->fast_ops->state(pcm->fast_op_arg);
859 }
860
861 /**
862  * \brief Synchronize stream position with hardware
863  * \param pcm PCM handle
864  * \return 0 on success otherwise a negative error code
865  *
866  * Note this function does not update the actual r/w pointer
867  * for applications. The function \link ::snd_pcm_avail_update \endlink
868  * have to be called before any read/write/begin+commit operation.
869  */
870 int snd_pcm_hwsync(snd_pcm_t *pcm)
871 {
872         assert(pcm);
873         assert(pcm->setup);
874         return pcm->fast_ops->hwsync(pcm->fast_op_arg);
875 }
876
877 /**
878  * \brief Obtain delay for a running PCM handle
879  * \param pcm PCM handle
880  * \param delayp Returned delay in frames
881  * \return 0 on success otherwise a negative error code
882  *
883  * Delay is distance between current application frame position and
884  * sound frame position.
885  * It's positive and less than buffer size in normal situation,
886  * negative on playback underrun and greater than buffer size on
887  * capture overrun.
888  *
889  * Note this function does not update the actual r/w pointer
890  * for applications. The function \link ::snd_pcm_avail_update \endlink
891  * have to be called before any read/write/begin+commit operation.
892  */
893 int snd_pcm_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp)
894 {
895         assert(pcm);
896         assert(pcm->setup);
897         return pcm->fast_ops->delay(pcm->fast_op_arg, delayp);
898 }
899
900 /**
901  * \brief Resume from suspend, no samples are lost
902  * \param pcm PCM handle
903  * \return 0 on success otherwise a negative error code
904  * \retval -EAGAIN resume can't be proceed immediately (audio hardware is probably still suspended)
905  * \retval -ENOSYS hardware doesn't support this feature
906  *
907  * This function can be used when the stream is in the suspend state
908  * to do the fine resume from this state. Not all hardware supports
909  * this feature, when an -ENOSYS error is returned, use the snd_pcm_prepare
910  * function to recovery.
911  */
912 int snd_pcm_resume(snd_pcm_t *pcm)
913 {
914         assert(pcm);
915         assert(pcm->setup);
916         return pcm->fast_ops->resume(pcm->fast_op_arg);
917 }
918
919 /**
920  * \brief Prepare PCM for use
921  * \param pcm PCM handle
922  * \return 0 on success otherwise a negative error code
923  */
924 int snd_pcm_prepare(snd_pcm_t *pcm)
925 {
926         assert(pcm);
927         assert(pcm->setup);
928         return pcm->fast_ops->prepare(pcm->fast_op_arg);
929 }
930
931 /**
932  * \brief Reset PCM position
933  * \param pcm PCM handle
934  * \return 0 on success otherwise a negative error code
935  *
936  * Reduce PCM delay to 0.
937  */
938 int snd_pcm_reset(snd_pcm_t *pcm)
939 {
940         assert(pcm);
941         assert(pcm->setup);
942         return pcm->fast_ops->reset(pcm->fast_op_arg);
943 }
944
945 /**
946  * \brief Start a PCM
947  * \param pcm PCM handle
948  * \return 0 on success otherwise a negative error code
949  */
950 int snd_pcm_start(snd_pcm_t *pcm)
951 {
952         assert(pcm);
953         assert(pcm->setup);
954         return pcm->fast_ops->start(pcm->fast_op_arg);
955 }
956
957 /**
958  * \brief Stop a PCM dropping pending frames
959  * \param pcm PCM handle
960  * \return 0 on success otherwise a negative error code
961  */
962 int snd_pcm_drop(snd_pcm_t *pcm)
963 {
964         assert(pcm);
965         assert(pcm->setup);
966         return pcm->fast_ops->drop(pcm->fast_op_arg);
967 }
968
969 /**
970  * \brief Stop a PCM preserving pending frames
971  * \param pcm PCM handle
972  * \return 0 on success otherwise a negative error code
973  * \retval -ESTRPIPE a suspend event occurred
974  *
975  * For playback wait for all pending frames to be played and then stop
976  * the PCM.
977  * For capture stop PCM permitting to retrieve residual frames.
978  */
979 int snd_pcm_drain(snd_pcm_t *pcm)
980 {
981         assert(pcm);
982         assert(pcm->setup);
983         return pcm->fast_ops->drain(pcm->fast_op_arg);
984 }
985
986 /**
987  * \brief Pause/resume PCM
988  * \param pcm PCM handle
989  * \param pause 0 = resume, 1 = pause
990  * \return 0 on success otherwise a negative error code
991  */
992 int snd_pcm_pause(snd_pcm_t *pcm, int enable)
993 {
994         assert(pcm);
995         assert(pcm->setup);
996         return pcm->fast_ops->pause(pcm->fast_op_arg, enable);
997 }
998
999 /**
1000  * \brief Move application frame position backward
1001  * \param pcm PCM handle
1002  * \param frames wanted displacement in frames
1003  * \return a positive number for actual displacement otherwise a
1004  * negative error code
1005  */
1006 snd_pcm_sframes_t snd_pcm_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
1007 {
1008         assert(pcm);
1009         assert(pcm->setup);
1010         assert(frames > 0);
1011         return pcm->fast_ops->rewind(pcm->fast_op_arg, frames);
1012 }
1013
1014 /**
1015  * \brief Write interleaved frames to a PCM
1016  * \param pcm PCM handle
1017  * \param buffer frames containing buffer
1018  * \param size frames to be written
1019  * \return a positive number of frames actually written otherwise a
1020  * negative error code
1021  * \retval -EBADFD PCM is not in the right state (#SND_PCM_STATE_PREPARED or #SND_PCM_STATE_RUNNING)
1022  * \retval -EPIPE an underrun occurred
1023  * \retval -ESTRPIPE a suspend event occurred (stream is suspended and waiting for an application recovery)
1024  *
1025  * If the blocking behaviour is selected, then routine waits until
1026  * all requested bytes are played or put to the playback ring buffer.
1027  * The count of bytes can be less only if a signal or underrun occurred.
1028  *
1029  * If the non-blocking behaviour is selected, then routine doesn't wait at all.
1030  */ 
1031 snd_pcm_sframes_t snd_pcm_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size)
1032 {
1033         assert(pcm);
1034         assert(size == 0 || buffer);
1035         assert(pcm->setup);
1036         assert(pcm->access == SND_PCM_ACCESS_RW_INTERLEAVED);
1037         return _snd_pcm_writei(pcm, buffer, size);
1038 }
1039
1040 /**
1041  * \brief Write non interleaved frames to a PCM
1042  * \param pcm PCM handle
1043  * \param bufs frames containing buffers (one for each channel)
1044  * \param size frames to be written
1045  * \return a positive number of frames actually written otherwise a
1046  * negative error code
1047  * \retval -EBADFD PCM is not in the right state (#SND_PCM_STATE_PREPARED or #SND_PCM_STATE_RUNNING)
1048  * \retval -EPIPE an underrun occurred
1049  * \retval -ESTRPIPE a suspend event occurred (stream is suspended and waiting for an application recovery)
1050  *
1051  * If the blocking behaviour is selected, then routine waits until
1052  * all requested bytes are played or put to the playback ring buffer.
1053  * The count of bytes can be less only if a signal or underrun occurred.
1054  *
1055  * If the non-blocking behaviour is selected, then routine doesn't wait at all.
1056  */ 
1057 snd_pcm_sframes_t snd_pcm_writen(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size)
1058 {
1059         assert(pcm);
1060         assert(size == 0 || bufs);
1061         assert(pcm->setup);
1062         assert(pcm->access == SND_PCM_ACCESS_RW_NONINTERLEAVED);
1063         return _snd_pcm_writen(pcm, bufs, size);
1064 }
1065
1066 /**
1067  * \brief Read interleaved frames from a PCM
1068  * \param pcm PCM handle
1069  * \param buffer frames containing buffer
1070  * \param size frames to be written
1071  * \return a positive number of frames actually read otherwise a
1072  * negative error code
1073  * \retval -EBADFD PCM is not in the right state (#SND_PCM_STATE_PREPARED or #SND_PCM_STATE_RUNNING)
1074  * \retval -EPIPE an overrun occurred
1075  * \retval -ESTRPIPE a suspend event occurred (stream is suspended and waiting for an application recovery)
1076  *
1077  * If the blocking behaviour was selected, then routine waits until
1078  * all requested bytes are filled. The count of bytes can be less only
1079  * if a signal or underrun occurred.
1080  *
1081  * If the non-blocking behaviour is selected, then routine doesn't wait at all.
1082  */ 
1083 snd_pcm_sframes_t snd_pcm_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size)
1084 {
1085         assert(pcm);
1086         assert(size == 0 || buffer);
1087         assert(pcm->setup);
1088         assert(pcm->access == SND_PCM_ACCESS_RW_INTERLEAVED);
1089         return _snd_pcm_readi(pcm, buffer, size);
1090 }
1091
1092 /**
1093  * \brief Read non interleaved frames to a PCM
1094  * \param pcm PCM handle
1095  * \param bufs frames containing buffers (one for each channel)
1096  * \param size frames to be written
1097  * \return a positive number of frames actually read otherwise a
1098  * negative error code
1099  * \retval -EBADFD PCM is not in the right state (#SND_PCM_STATE_PREPARED or #SND_PCM_STATE_RUNNING)
1100  * \retval -EPIPE an overrun occurred
1101  * \retval -ESTRPIPE a suspend event occurred (stream is suspended and waiting for an application recovery)
1102  *
1103  * If the blocking behaviour was selected, then routine waits until
1104  * all requested bytes are filled. The count of bytes can be less only
1105  * if a signal or underrun occurred.
1106  *
1107  * If the non-blocking behaviour is selected, then routine doesn't wait at all.
1108  */ 
1109 snd_pcm_sframes_t snd_pcm_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size)
1110 {
1111         assert(pcm);
1112         assert(size == 0 || bufs);
1113         assert(pcm->setup);
1114         assert(pcm->access == SND_PCM_ACCESS_RW_NONINTERLEAVED);
1115         return _snd_pcm_readn(pcm, bufs, size);
1116 }
1117
1118 /**
1119  * \brief Link two PCMs
1120  * \param pcm1 first PCM handle
1121  * \param pcm2 first PCM handle
1122  * \return 0 on success otherwise a negative error code
1123  *
1124  * The two PCMs will start/stop/prepare in sync.
1125  */ 
1126 int snd_pcm_link(snd_pcm_t *pcm1, snd_pcm_t *pcm2)
1127 {
1128         int fd1 = _snd_pcm_link_descriptor(pcm1);
1129         int fd2 = _snd_pcm_link_descriptor(pcm2);
1130         if (fd1 < 0 || fd2 < 0)
1131                 return -ENOSYS;
1132         if (ioctl(fd1, SNDRV_PCM_IOCTL_LINK, fd2) < 0) {
1133                 SYSERR("SNDRV_PCM_IOCTL_LINK failed");
1134                 return -errno;
1135         }
1136         return 0;
1137 }
1138
1139 /**
1140  * \brief Remove a PCM from a linked group
1141  * \param pcm PCM handle
1142  * \return 0 on success otherwise a negative error code
1143  */
1144 int snd_pcm_unlink(snd_pcm_t *pcm)
1145 {
1146         int fd;
1147         fd = _snd_pcm_link_descriptor(pcm);
1148         if (ioctl(fd, SNDRV_PCM_IOCTL_UNLINK) < 0) {
1149                 SYSERR("SNDRV_PCM_IOCTL_UNLINK failed");
1150                 return -errno;
1151         }
1152         return 0;
1153 }
1154
1155 /**
1156  * \brief get count of poll descriptors for PCM handle
1157  * \param pcm PCM handle
1158  * \return count of poll descriptors
1159  */
1160 int snd_pcm_poll_descriptors_count(snd_pcm_t *pcm)
1161 {
1162         assert(pcm);
1163         return 1;
1164 }
1165
1166
1167 /**
1168  * \brief get poll descriptors
1169  * \param pcm PCM handle
1170  * \param pfds array of poll descriptors
1171  * \param space space in the poll descriptor array
1172  * \return count of filled descriptors
1173  */
1174 int snd_pcm_poll_descriptors(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int space)
1175 {
1176         assert(pcm && pfds);
1177         if (space >= 1 && pfds) {
1178                 pfds->fd = pcm->poll_fd;
1179                 pfds->events = pcm->stream == SND_PCM_STREAM_PLAYBACK ? (POLLOUT|POLLERR) : (POLLIN|POLLERR);
1180         } else
1181                 return 0;
1182         return 1;
1183 }
1184
1185 /**
1186  * \brief get returned events from poll descriptors
1187  * \param pcm PCM handle
1188  * \param pfds array of poll descriptors
1189  * \param nfds count of poll descriptors
1190  * \param revents returned events
1191  * \return zero if success, otherwise a negative error code
1192  */
1193 int snd_pcm_poll_descriptors_revents(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int nfds, unsigned short *revents)
1194 {
1195         assert(pcm && pfds && revents);
1196         if (nfds == 1) {
1197                 *revents = pfds->revents;
1198                 return 0;
1199         }
1200         return -EINVAL;
1201 }
1202
1203 #ifndef DOC_HIDDEN
1204 #define STATE(v) [SND_PCM_STATE_##v] = #v
1205 #define STREAM(v) [SND_PCM_STREAM_##v] = #v
1206 #define READY(v) [SND_PCM_READY_##v] = #v
1207 #define XRUN(v) [SND_PCM_XRUN_##v] = #v
1208 #define SILENCE(v) [SND_PCM_SILENCE_##v] = #v
1209 #define TSTAMP(v) [SND_PCM_TSTAMP_##v] = #v
1210 #define ACCESS(v) [SND_PCM_ACCESS_##v] = #v
1211 #define START(v) [SND_PCM_START_##v] = #v
1212 #define HW_PARAM(v) [SND_PCM_HW_PARAM_##v] = #v
1213 #define SW_PARAM(v) [SND_PCM_SW_PARAM_##v] = #v
1214 #define FORMAT(v) [SND_PCM_FORMAT_##v] = #v
1215 #define SUBFORMAT(v) [SND_PCM_SUBFORMAT_##v] = #v 
1216
1217 #define FORMATD(v, d) [SND_PCM_FORMAT_##v] = d
1218 #define SUBFORMATD(v, d) [SND_PCM_SUBFORMAT_##v] = d 
1219
1220 static const char *snd_pcm_stream_names[] = {
1221         STREAM(PLAYBACK),
1222         STREAM(CAPTURE),
1223 };
1224
1225 static const char *snd_pcm_state_names[] = {
1226         STATE(OPEN),
1227         STATE(SETUP),
1228         STATE(PREPARED),
1229         STATE(RUNNING),
1230         STATE(XRUN),
1231         STATE(DRAINING),
1232         STATE(PAUSED),
1233         STATE(SUSPENDED),
1234 };
1235
1236 static const char *snd_pcm_access_names[] = {
1237         ACCESS(MMAP_INTERLEAVED), 
1238         ACCESS(MMAP_NONINTERLEAVED),
1239         ACCESS(MMAP_COMPLEX),
1240         ACCESS(RW_INTERLEAVED),
1241         ACCESS(RW_NONINTERLEAVED),
1242 };
1243
1244 static const char *snd_pcm_format_names[] = {
1245         FORMAT(S8),
1246         FORMAT(U8),
1247         FORMAT(S16_LE),
1248         FORMAT(S16_BE),
1249         FORMAT(U16_LE),
1250         FORMAT(U16_BE),
1251         FORMAT(S24_LE),
1252         FORMAT(S24_BE),
1253         FORMAT(U24_LE),
1254         FORMAT(U24_BE),
1255         FORMAT(S32_LE),
1256         FORMAT(S32_BE),
1257         FORMAT(U32_LE),
1258         FORMAT(U32_BE),
1259         FORMAT(FLOAT_LE),
1260         FORMAT(FLOAT_BE),
1261         FORMAT(FLOAT64_LE),
1262         FORMAT(FLOAT64_BE),
1263         FORMAT(IEC958_SUBFRAME_LE),
1264         FORMAT(IEC958_SUBFRAME_BE),
1265         FORMAT(MU_LAW),
1266         FORMAT(A_LAW),
1267         FORMAT(IMA_ADPCM),
1268         FORMAT(MPEG),
1269         FORMAT(GSM),
1270         FORMAT(SPECIAL),
1271         FORMAT(S24_3LE),
1272         FORMAT(S24_3BE),
1273         FORMAT(U24_3LE),
1274         FORMAT(U24_3BE),
1275         FORMAT(S20_3LE),
1276         FORMAT(S20_3BE),
1277         FORMAT(U20_3LE),
1278         FORMAT(U20_3BE),
1279         FORMAT(S18_3LE),
1280         FORMAT(S18_3BE),
1281         FORMAT(U18_3LE),
1282         FORMAT(U18_3BE),
1283 };
1284
1285 static const char *snd_pcm_format_descriptions[] = {
1286         FORMATD(S8, "Signed 8 bit"), 
1287         FORMATD(U8, "Unsigned 8 bit"),
1288         FORMATD(S16_LE, "Signed 16 bit Little Endian"),
1289         FORMATD(S16_BE, "Signed 16 bit Big Endian"),
1290         FORMATD(U16_LE, "Unsigned 16 bit Little Endian"),
1291         FORMATD(U16_BE, "Unsigned 16 bit Big Endian"),
1292         FORMATD(S24_LE, "Signed 24 bit Little Endian"),
1293         FORMATD(S24_BE, "Signed 24 bit Big Endian"),
1294         FORMATD(U24_LE, "Unsigned 24 bit Little Endian"),
1295         FORMATD(U24_BE, "Unsigned 24 bit Big Endian"),
1296         FORMATD(S32_LE, "Signed 32 bit Little Endian"),
1297         FORMATD(S32_BE, "Signed 32 bit Big Endian"),
1298         FORMATD(U32_LE, "Unsigned 32 bit Little Endian"),
1299         FORMATD(U32_BE, "Unsigned 32 bit Big Endian"),
1300         FORMATD(FLOAT_LE, "Float 32 bit Little Endian"),
1301         FORMATD(FLOAT_BE, "Float 32 bit Big Endian"),
1302         FORMATD(FLOAT64_LE, "Float 64 bit Little Endian"),
1303         FORMATD(FLOAT64_BE, "Float 64 bit Big Endian"),
1304         FORMATD(IEC958_SUBFRAME_LE, "IEC-958 Little Endian"),
1305         FORMATD(IEC958_SUBFRAME_BE, "IEC-958 Big Endian"),
1306         FORMATD(MU_LAW, "Mu-Law"),
1307         FORMATD(A_LAW, "A-Law"),
1308         FORMATD(IMA_ADPCM, "Ima-ADPCM"),
1309         FORMATD(MPEG, "MPEG"),
1310         FORMATD(GSM, "GSM"),
1311         FORMATD(SPECIAL, "Special"),
1312         FORMATD(S24_3LE, "Signed 24 bit Little Endian in 3bytes"),
1313         FORMATD(S24_3BE, "Signed 24 bit Big Endian in 3bytes"),
1314         FORMATD(U24_3LE, "Unsigned 24 bit Little Endian in 3bytes"),
1315         FORMATD(U24_3BE, "Unsigned 24 bit Big Endian in 3bytes"),
1316         FORMATD(S20_3LE, "Signed 20 bit Little Endian in 3bytes"),
1317         FORMATD(S20_3BE, "Signed 20 bit Big Endian in 3bytes"),
1318         FORMATD(U20_3LE, "Unsigned 20 bit Little Endian in 3bytes"),
1319         FORMATD(U20_3BE, "Unsigned 20 bit Big Endian in 3bytes"),
1320         FORMATD(S18_3LE, "Signed 18 bit Little Endian in 3bytes"),
1321         FORMATD(S18_3BE, "Signed 18 bit Big Endian in 3bytes"),
1322         FORMATD(U18_3LE, "Unsigned 18 bit Little Endian in 3bytes"),
1323         FORMATD(U18_3BE, "Unsigned 18 bit Big Endian in 3bytes"),
1324 };
1325
1326 static const char *snd_pcm_subformat_names[] = {
1327         SUBFORMAT(STD), 
1328 };
1329
1330 static const char *snd_pcm_subformat_descriptions[] = {
1331         SUBFORMATD(STD, "Standard"), 
1332 };
1333
1334 static const char *snd_pcm_start_mode_names[] = {
1335         START(EXPLICIT),
1336         START(DATA),
1337 };
1338
1339 static const char *snd_pcm_xrun_mode_names[] = {
1340         XRUN(NONE),
1341         XRUN(STOP),
1342 };
1343
1344 static const char *snd_pcm_tstamp_mode_names[] = {
1345         TSTAMP(NONE),
1346         TSTAMP(MMAP),
1347 };
1348 #endif
1349
1350 /**
1351  * \brief get name of PCM stream
1352  * \param stream PCM stream
1353  * \return ascii name of PCM stream
1354  */
1355 const char *snd_pcm_stream_name(snd_pcm_stream_t stream)
1356 {
1357         assert(stream <= SND_PCM_STREAM_LAST);
1358         return snd_pcm_stream_names[stream];
1359 }
1360
1361 /**
1362  * \brief get name of PCM access type
1363  * \param access PCM access type
1364  * \return ascii name of PCM access type
1365  */
1366 const char *snd_pcm_access_name(snd_pcm_access_t acc)
1367 {
1368         if (acc > SND_PCM_ACCESS_LAST)
1369                 return NULL;
1370         return snd_pcm_access_names[acc];
1371 }
1372
1373 /**
1374  * \brief get name of PCM sample format
1375  * \param format PCM sample format
1376  * \return ascii name of PCM sample format
1377  */
1378 const char *snd_pcm_format_name(snd_pcm_format_t format)
1379 {
1380         if (format > SND_PCM_FORMAT_LAST)
1381                 return NULL;
1382         return snd_pcm_format_names[format];
1383 }
1384
1385 /**
1386  * \brief get description of PCM sample format
1387  * \param format PCM sample format
1388  * \return ascii description of PCM sample format
1389  */
1390 const char *snd_pcm_format_description(snd_pcm_format_t format)
1391 {
1392         if (format > SND_PCM_FORMAT_LAST)
1393                 return NULL;
1394         return snd_pcm_format_descriptions[format];
1395 }
1396
1397 /**
1398  * \brief get PCM sample format from name
1399  * \param name PCM sample format name (case insensitive)
1400  * \return PCM sample format
1401  */
1402 snd_pcm_format_t snd_pcm_format_value(const char* name)
1403 {
1404         snd_pcm_format_t format;
1405         for (format = 0; format <= SND_PCM_FORMAT_LAST; format++) {
1406                 if (snd_pcm_format_names[format] &&
1407                     strcasecmp(name, snd_pcm_format_names[format]) == 0) {
1408                         return format;
1409                 }
1410         }
1411         for (format = 0; format <= SND_PCM_FORMAT_LAST; format++) {
1412                 if (snd_pcm_format_descriptions[format] &&
1413                     strcasecmp(name, snd_pcm_format_descriptions[format]) == 0) {
1414                         return format;
1415                 }
1416         }
1417         return SND_PCM_FORMAT_UNKNOWN;
1418 }
1419
1420 /**
1421  * \brief get name of PCM sample subformat
1422  * \param format PCM sample subformat
1423  * \return ascii name of PCM sample subformat
1424  */
1425 const char *snd_pcm_subformat_name(snd_pcm_subformat_t subformat)
1426 {
1427         if (subformat > SND_PCM_SUBFORMAT_LAST)
1428                 return NULL;
1429         return snd_pcm_subformat_names[subformat];
1430 }
1431
1432 /**
1433  * \brief get description of PCM sample subformat
1434  * \param subformat PCM sample subformat
1435  * \return ascii description of PCM sample subformat
1436  */
1437 const char *snd_pcm_subformat_description(snd_pcm_subformat_t subformat)
1438 {
1439         if (subformat > SND_PCM_SUBFORMAT_LAST)
1440                 return NULL;
1441         return snd_pcm_subformat_descriptions[subformat];
1442 }
1443
1444 /**
1445  * \brief (DEPRECATED) get name of PCM start mode setting
1446  * \param mode PCM start mode
1447  * \return ascii name of PCM start mode setting
1448  */
1449 const char *snd_pcm_start_mode_name(snd_pcm_start_t mode)
1450 {
1451         assert(mode <= SND_PCM_START_LAST);
1452         return snd_pcm_start_mode_names[mode];
1453 }
1454
1455 #ifndef DOC_HIDDEN
1456 link_warning(snd_pcm_start_mode_name, "Warning: start_mode is deprecated, consider to use start_threshold");
1457 #endif
1458
1459 /**
1460  * \brief (DEPRECATED) get name of PCM xrun mode setting
1461  * \param mode PCM xrun mode
1462  * \return ascii name of PCM xrun mode setting
1463  */
1464 const char *snd_pcm_xrun_mode_name(snd_pcm_xrun_t mode)
1465 {
1466         assert(mode <= SND_PCM_XRUN_LAST);
1467         return snd_pcm_xrun_mode_names[mode];
1468 }
1469
1470 #ifndef DOC_HIDDEN
1471 link_warning(snd_pcm_xrun_mode_name, "Warning: xrun_mode is deprecated, consider to use stop_threshold");
1472 #endif
1473
1474 /**
1475  * \brief get name of PCM tstamp mode setting
1476  * \param mode PCM tstamp mode
1477  * \return ascii name of PCM tstamp mode setting
1478  */
1479 const char *snd_pcm_tstamp_mode_name(snd_pcm_tstamp_t mode)
1480 {
1481         if (mode > SND_PCM_TSTAMP_LAST)
1482                 return NULL;
1483         return snd_pcm_tstamp_mode_names[mode];
1484 }
1485
1486 /**
1487  * \brief get name of PCM state
1488  * \param state PCM state
1489  * \return ascii name of PCM state
1490  */
1491 const char *snd_pcm_state_name(snd_pcm_state_t state)
1492 {
1493         if (state > SND_PCM_STATE_LAST)
1494                 return NULL;
1495         return snd_pcm_state_names[state];
1496 }
1497
1498 /**
1499  * \brief Dump current hardware setup for PCM
1500  * \param pcm PCM handle
1501  * \param out Output handle
1502  * \return 0 on success otherwise a negative error code
1503  */
1504 int snd_pcm_dump_hw_setup(snd_pcm_t *pcm, snd_output_t *out)
1505 {
1506         assert(pcm);
1507         assert(out);
1508         assert(pcm->setup);
1509         snd_output_printf(out, "stream       : %s\n", snd_pcm_stream_name(pcm->stream));
1510         snd_output_printf(out, "access       : %s\n", snd_pcm_access_name(pcm->access));
1511         snd_output_printf(out, "format       : %s\n", snd_pcm_format_name(pcm->format));
1512         snd_output_printf(out, "subformat    : %s\n", snd_pcm_subformat_name(pcm->subformat));
1513         snd_output_printf(out, "channels     : %u\n", pcm->channels);
1514         snd_output_printf(out, "rate         : %u\n", pcm->rate);
1515         snd_output_printf(out, "exact rate   : %g (%u/%u)\n", (double) pcm->rate_num / pcm->rate_den, pcm->rate_num, pcm->rate_den);
1516         snd_output_printf(out, "msbits       : %u\n", pcm->msbits);
1517         snd_output_printf(out, "buffer_size  : %lu\n", pcm->buffer_size);
1518         snd_output_printf(out, "period_size  : %lu\n", pcm->period_size);
1519         snd_output_printf(out, "period_time  : %u\n", pcm->period_time);
1520         snd_output_printf(out, "tick_time    : %u\n", pcm->tick_time);
1521         return 0;
1522 }
1523
1524 /**
1525  * \brief Dump current software setup for PCM
1526  * \param pcm PCM handle
1527  * \param out Output handle
1528  * \return 0 on success otherwise a negative error code
1529  */
1530 int snd_pcm_dump_sw_setup(snd_pcm_t *pcm, snd_output_t *out)
1531 {
1532         assert(pcm);
1533         assert(out);
1534         assert(pcm->setup);
1535         snd_output_printf(out, "tstamp_mode  : %s\n", snd_pcm_tstamp_mode_name(pcm->tstamp_mode));
1536         snd_output_printf(out, "period_step  : %d\n", pcm->period_step);
1537         snd_output_printf(out, "sleep_min    : %d\n", pcm->sleep_min);
1538         snd_output_printf(out, "avail_min    : %ld\n", pcm->avail_min);
1539         snd_output_printf(out, "xfer_align   : %ld\n", pcm->xfer_align);
1540         snd_output_printf(out, "start_threshold  : %ld\n", pcm->start_threshold);
1541         snd_output_printf(out, "stop_threshold   : %ld\n", pcm->stop_threshold);
1542         snd_output_printf(out, "silence_threshold: %ld\n", pcm->silence_threshold);
1543         snd_output_printf(out, "silence_size : %ld\n", pcm->silence_size);
1544         snd_output_printf(out, "boundary     : %ld\n", pcm->boundary);
1545         return 0;
1546 }
1547
1548 /**
1549  * \brief Dump current setup (hardware and software) for PCM
1550  * \param pcm PCM handle
1551  * \param out Output handle
1552  * \return 0 on success otherwise a negative error code
1553  */
1554 int snd_pcm_dump_setup(snd_pcm_t *pcm, snd_output_t *out)
1555 {
1556         snd_pcm_dump_hw_setup(pcm, out);
1557         snd_pcm_dump_sw_setup(pcm, out);
1558         return 0;
1559 }
1560
1561 /**
1562  * \brief Dump status
1563  * \param status Status container
1564  * \param out Output handle
1565  * \return 0 on success otherwise a negative error code
1566  */
1567 int snd_pcm_status_dump(snd_pcm_status_t *status, snd_output_t *out)
1568 {
1569         assert(status);
1570         snd_output_printf(out, "state       : %s\n", snd_pcm_state_name((snd_pcm_state_t) status->state));
1571         snd_output_printf(out, "trigger_time: %ld.%06ld\n",
1572                 status->trigger_tstamp.tv_sec, status->trigger_tstamp.tv_usec);
1573         snd_output_printf(out, "tstamp      : %ld.%06ld\n",
1574                 status->tstamp.tv_sec, status->tstamp.tv_usec);
1575         snd_output_printf(out, "delay       : %ld\n", (long)status->delay);
1576         snd_output_printf(out, "avail       : %ld\n", (long)status->avail);
1577         snd_output_printf(out, "avail_max   : %ld\n", (long)status->avail_max);
1578         return 0;
1579 }
1580
1581 /**
1582  * \brief Dump PCM info
1583  * \param pcm PCM handle
1584  * \param out Output handle
1585  * \return 0 on success otherwise a negative error code
1586  */
1587 int snd_pcm_dump(snd_pcm_t *pcm, snd_output_t *out)
1588 {
1589         assert(pcm);
1590         assert(out);
1591         pcm->ops->dump(pcm->op_arg, out);
1592         return 0;
1593 }
1594
1595 /**
1596  * \brief Convert bytes in frames for a PCM
1597  * \param pcm PCM handle
1598  * \param bytes quantity in bytes
1599  * \return quantity expressed in frames
1600  */
1601 snd_pcm_sframes_t snd_pcm_bytes_to_frames(snd_pcm_t *pcm, ssize_t bytes)
1602 {
1603         assert(pcm);
1604         assert(pcm->setup);
1605         return bytes * 8 / pcm->frame_bits;
1606 }
1607
1608 /**
1609  * \brief Convert frames in bytes for a PCM
1610  * \param pcm PCM handle
1611  * \param frames quantity in frames
1612  * \return quantity expressed in bytes
1613  */
1614 ssize_t snd_pcm_frames_to_bytes(snd_pcm_t *pcm, snd_pcm_sframes_t frames)
1615 {
1616         assert(pcm);
1617         assert(pcm->setup);
1618         return frames * pcm->frame_bits / 8;
1619 }
1620
1621 /**
1622  * \brief Convert bytes in samples for a PCM
1623  * \param pcm PCM handle
1624  * \param bytes quantity in bytes
1625  * \return quantity expressed in samples
1626  */
1627 long snd_pcm_bytes_to_samples(snd_pcm_t *pcm, ssize_t bytes)
1628 {
1629         assert(pcm);
1630         assert(pcm->setup);
1631         return bytes * 8 / pcm->sample_bits;
1632 }
1633
1634 /**
1635  * \brief Convert samples in bytes for a PCM
1636  * \param pcm PCM handle
1637  * \param samples quantity in samples
1638  * \return quantity expressed in bytes
1639  */
1640 ssize_t snd_pcm_samples_to_bytes(snd_pcm_t *pcm, long samples)
1641 {
1642         assert(pcm);
1643         assert(pcm->setup);
1644         return samples * pcm->sample_bits / 8;
1645 }
1646
1647 /**
1648  * \brief Add an async handler for a PCM
1649  * \param handler Returned handler handle
1650  * \param pcm PCM handle
1651  * \param callback Callback function
1652  * \param private_data Callback private data
1653  * \return 0 otherwise a negative error code on failure
1654  *
1655  * The asynchronous callback is called when period boundary elapses.
1656  */
1657 int snd_async_add_pcm_handler(snd_async_handler_t **handler, snd_pcm_t *pcm, 
1658                               snd_async_callback_t callback, void *private_data)
1659 {
1660         int err;
1661         int was_empty;
1662         snd_async_handler_t *h;
1663         err = snd_async_add_handler(&h, _snd_pcm_async_descriptor(pcm),
1664                                     callback, private_data);
1665         if (err < 0)
1666                 return err;
1667         h->type = SND_ASYNC_HANDLER_PCM;
1668         h->u.pcm = pcm;
1669         was_empty = list_empty(&pcm->async_handlers);
1670         list_add_tail(&h->hlist, &pcm->async_handlers);
1671         if (was_empty) {
1672                 err = snd_pcm_async(pcm, snd_async_handler_get_signo(h), getpid());
1673                 if (err < 0) {
1674                         snd_async_del_handler(h);
1675                         return err;
1676                 }
1677         }
1678         *handler = h;
1679         return 0;
1680 }
1681
1682 /**
1683  * \brief Return PCM handle related to an async handler
1684  * \param handler Async handler handle
1685  * \return PCM handle
1686  */
1687 snd_pcm_t *snd_async_handler_get_pcm(snd_async_handler_t *handler)
1688 {
1689         assert(handler->type = SND_ASYNC_HANDLER_PCM);
1690         return handler->u.pcm;
1691 }
1692
1693 static int snd_pcm_open_conf(snd_pcm_t **pcmp, const char *name,
1694                              snd_config_t *pcm_root, snd_config_t *pcm_conf,
1695                              snd_pcm_stream_t stream, int mode)
1696 {
1697         const char *str;
1698         char buf[256];
1699         int err;
1700         snd_config_t *conf, *type_conf = NULL;
1701         snd_config_iterator_t i, next;
1702         const char *id;
1703         const char *lib = NULL, *open_name = NULL;
1704         int (*open_func)(snd_pcm_t **, const char *, 
1705                          snd_config_t *, snd_config_t *, 
1706                          snd_pcm_stream_t, int) = NULL;
1707 #ifndef PIC
1708         extern void *snd_pcm_open_symbols(void);
1709 #endif
1710         void *h;
1711         if (snd_config_get_type(pcm_conf) != SND_CONFIG_TYPE_COMPOUND) {
1712                 char *val;
1713                 id = NULL;
1714                 snd_config_get_id(pcm_conf, &id);
1715                 val = NULL;
1716                 snd_config_get_ascii(pcm_conf, &val);
1717                 SNDERR("Invalid type for PCM %s%sdefinition (id: %s, value: %s)", name ? name : "", name ? " " : "", id, val);
1718                 if (val)
1719                         free(val);
1720                 return -EINVAL;
1721         }
1722         err = snd_config_search(pcm_conf, "type", &conf);
1723         if (err < 0) {
1724                 SNDERR("type is not defined");
1725                 return err;
1726         }
1727         err = snd_config_get_id(conf, &id);
1728         if (err < 0) {
1729                 SNDERR("unable to get id");
1730                 return err;
1731         }
1732         err = snd_config_get_string(conf, &str);
1733         if (err < 0) {
1734                 SNDERR("Invalid type for %s", id);
1735                 return err;
1736         }
1737         err = snd_config_search_definition(pcm_root, "pcm_type", str, &type_conf);
1738         if (err >= 0) {
1739                 if (snd_config_get_type(type_conf) != SND_CONFIG_TYPE_COMPOUND) {
1740                         SNDERR("Invalid type for PCM type %s definition", str);
1741                         goto _err;
1742                 }
1743                 snd_config_for_each(i, next, type_conf) {
1744                         snd_config_t *n = snd_config_iterator_entry(i);
1745                         const char *id;
1746                         if (snd_config_get_id(n, &id) < 0)
1747                                 continue;
1748                         if (strcmp(id, "comment") == 0)
1749                                 continue;
1750                         if (strcmp(id, "lib") == 0) {
1751                                 err = snd_config_get_string(n, &lib);
1752                                 if (err < 0) {
1753                                         SNDERR("Invalid type for %s", id);
1754                                         goto _err;
1755                                 }
1756                                 continue;
1757                         }
1758                         if (strcmp(id, "open") == 0) {
1759                                 err = snd_config_get_string(n, &open_name);
1760                                 if (err < 0) {
1761                                         SNDERR("Invalid type for %s", id);
1762                                         goto _err;
1763                                 }
1764                                 continue;
1765                         }
1766                         SNDERR("Unknown field %s", id);
1767                         err = -EINVAL;
1768                         goto _err;
1769                 }
1770         }
1771         if (!open_name) {
1772                 open_name = buf;
1773                 snprintf(buf, sizeof(buf), "_snd_pcm_%s_open", str);
1774         }
1775 #ifndef PIC
1776         snd_pcm_open_symbols(); /* this call is for static linking only */
1777 #endif
1778         h = snd_dlopen(lib, RTLD_NOW);
1779         if (h)
1780                 open_func = snd_dlsym(h, open_name, SND_DLSYM_VERSION(SND_PCM_DLSYM_VERSION));
1781         err = 0;
1782         if (!h) {
1783                 SNDERR("Cannot open shared library %s", lib);
1784                 err = -ENOENT;
1785         } else if (!open_func) {
1786                 SNDERR("symbol %s is not defined inside %s", open_name, lib);
1787                 snd_dlclose(h);
1788                 err = -ENXIO;
1789         }
1790        _err:
1791         if (type_conf)
1792                 snd_config_delete(type_conf);
1793         return err >= 0 ? open_func(pcmp, name, pcm_root, pcm_conf, stream, mode) : err;
1794 }
1795
1796 static int snd_pcm_open_noupdate(snd_pcm_t **pcmp, snd_config_t *root,
1797                                  const char *name, snd_pcm_stream_t stream, int mode)
1798 {
1799         int err;
1800         snd_config_t *pcm_conf;
1801         err = snd_config_search_definition(root, "pcm", name, &pcm_conf);
1802         if (err < 0) {
1803                 SNDERR("Unknown PCM %s", name);
1804                 return err;
1805         }
1806         err = snd_pcm_open_conf(pcmp, name, root, pcm_conf, stream, mode);
1807         snd_config_delete(pcm_conf);
1808         return err;
1809 }
1810
1811 /**
1812  * \brief Opens a PCM
1813  * \param pcmp Returned PCM handle
1814  * \param name ASCII identifier of the PCM handle
1815  * \param stream Wanted stream
1816  * \param mode Open mode (see #SND_PCM_NONBLOCK, #SND_PCM_ASYNC)
1817  * \return 0 on success otherwise a negative error code
1818  */
1819 int snd_pcm_open(snd_pcm_t **pcmp, const char *name, 
1820                  snd_pcm_stream_t stream, int mode)
1821 {
1822         int err;
1823         assert(pcmp && name);
1824         err = snd_config_update();
1825         if (err < 0)
1826                 return err;
1827         return snd_pcm_open_noupdate(pcmp, snd_config, name, stream, mode);
1828 }
1829
1830 /**
1831  * \brief Opens a PCM using local configuration
1832  * \param pcmp Returned PCM handle
1833  * \param name ASCII identifier of the PCM handle
1834  * \param stream Wanted stream
1835  * \param mode Open mode (see #SND_PCM_NONBLOCK, #SND_PCM_ASYNC)
1836  * \param lconf Local configuration
1837  * \return 0 on success otherwise a negative error code
1838  */
1839 int snd_pcm_open_lconf(snd_pcm_t **pcmp, const char *name, 
1840                        snd_pcm_stream_t stream, int mode,
1841                        snd_config_t *lconf)
1842 {
1843         assert(pcmp && name && lconf);
1844         return snd_pcm_open_noupdate(pcmp, lconf, name, stream, mode);
1845 }
1846
1847 #ifndef DOC_HIDDEN
1848 int snd_pcm_new(snd_pcm_t **pcmp, snd_pcm_type_t type, const char *name,
1849                 snd_pcm_stream_t stream, int mode)
1850 {
1851         snd_pcm_t *pcm;
1852         pcm = calloc(1, sizeof(*pcm));
1853         if (!pcm)
1854                 return -ENOMEM;
1855         pcm->type = type;
1856         if (name)
1857                 pcm->name = strdup(name);
1858         pcm->stream = stream;
1859         pcm->mode = mode;
1860         pcm->op_arg = pcm;
1861         pcm->fast_op_arg = pcm;
1862         INIT_LIST_HEAD(&pcm->async_handlers);
1863         *pcmp = pcm;
1864         return 0;
1865 }
1866
1867 int snd_pcm_open_slave(snd_pcm_t **pcmp, snd_config_t *root,
1868                        snd_config_t *conf, snd_pcm_stream_t stream,
1869                        int mode)
1870 {
1871         const char *str;
1872         if (snd_config_get_string(conf, &str) >= 0)
1873                 return snd_pcm_open_noupdate(pcmp, root, str, stream, mode);
1874         return snd_pcm_open_conf(pcmp, NULL, root, conf, stream, mode);
1875 }
1876 #endif
1877
1878 /**
1879  * \brief Wait for a PCM to become ready
1880  * \param pcm PCM handle
1881  * \param timeout maximum time in milliseconds to wait
1882  * \return a positive value on success otherwise a negative error code
1883  * \retval 0 timeout occurred
1884  * \retval 1 PCM stream is ready for I/O
1885  */
1886 int snd_pcm_wait(snd_pcm_t *pcm, int timeout)
1887 {
1888         struct pollfd pfd;
1889         int err;
1890         err = snd_pcm_poll_descriptors(pcm, &pfd, 1);
1891         assert(err == 1);
1892         err = poll(&pfd, 1, timeout);
1893         if (err < 0)
1894                 return -errno;
1895         return err > 0 ? 1 : 0;
1896 }
1897
1898 /**
1899  * \brief Return number of frames ready to be read/written
1900  * \param pcm PCM handle
1901  * \return a positive number of frames ready otherwise a negative
1902  * error code
1903  *
1904  * On capture does all the actions needed to transport to application
1905  * level all the ready frames across underlying layers.
1906  */
1907 snd_pcm_sframes_t snd_pcm_avail_update(snd_pcm_t *pcm)
1908 {
1909         return pcm->fast_ops->avail_update(pcm->fast_op_arg);
1910 }
1911
1912 /**
1913  * \brief Silence an area
1914  * \param dst_area area specification
1915  * \param dst_offset offset in frames inside area
1916  * \param samples samples to silence
1917  * \param format PCM sample format
1918  * \return 0 on success otherwise a negative error code
1919  */
1920 int snd_pcm_area_silence(const snd_pcm_channel_area_t *dst_area, snd_pcm_uframes_t dst_offset,
1921                          unsigned int samples, snd_pcm_format_t format)
1922 {
1923         /* FIXME: sub byte resolution and odd dst_offset */
1924         char *dst;
1925         unsigned int dst_step;
1926         int width;
1927         u_int64_t silence;
1928         if (!dst_area->addr)
1929                 return 0;
1930         dst = snd_pcm_channel_area_addr(dst_area, dst_offset);
1931         width = snd_pcm_format_physical_width(format);
1932         silence = snd_pcm_format_silence_64(format);
1933         if (dst_area->step == (unsigned int) width) {
1934                 unsigned int dwords = samples * width / 64;
1935                 samples -= dwords * 64 / width;
1936                 while (dwords-- > 0)
1937                         *((u_int64_t*)dst)++ = silence;
1938                 if (samples == 0)
1939                         return 0;
1940         }
1941         dst_step = dst_area->step / 8;
1942         switch (width) {
1943         case 4: {
1944                 u_int8_t s0 = silence & 0xf0;
1945                 u_int8_t s1 = silence & 0x0f;
1946                 int dstbit = dst_area->first % 8;
1947                 int dstbit_step = dst_area->step % 8;
1948                 while (samples-- > 0) {
1949                         if (dstbit) {
1950                                 *dst &= 0xf0;
1951                                 *dst |= s1;
1952                         } else {
1953                                 *dst &= 0x0f;
1954                                 *dst |= s0;
1955                         }
1956                         dst += dst_step;
1957                         dstbit += dstbit_step;
1958                         if (dstbit == 8) {
1959                                 dst++;
1960                                 dstbit = 0;
1961                         }
1962                 }
1963                 break;
1964         }
1965         case 8: {
1966                 u_int8_t sil = silence;
1967                 while (samples-- > 0) {
1968                         *dst = sil;
1969                         dst += dst_step;
1970                 }
1971                 break;
1972         }
1973         case 16: {
1974                 u_int16_t sil = silence;
1975                 while (samples-- > 0) {
1976                         *(u_int16_t*)dst = sil;
1977                         dst += dst_step;
1978                 }
1979                 break;
1980         }
1981         case 24:
1982 #ifdef SNDRV_LITTLE_ENDIAN
1983                 *(dst + 0) = silence >> 0;
1984                 *(dst + 1) = silence >> 8;
1985                 *(dst + 2) = silence >> 16;
1986 #else
1987                 *(dst + 2) = silence >> 0;
1988                 *(dst + 1) = silence >> 8;
1989                 *(dst + 0) = silence >> 16;
1990 #endif
1991                 break;
1992         case 32: {
1993                 u_int32_t sil = silence;
1994                 while (samples-- > 0) {
1995                         *(u_int32_t*)dst = sil;
1996                         dst += dst_step;
1997                 }
1998                 break;
1999         }
2000         case 64: {
2001                 while (samples-- > 0) {
2002                         *(u_int64_t*)dst = silence;
2003                         dst += dst_step;
2004                 }
2005                 break;
2006         }
2007         default:
2008                 assert(0);
2009         }
2010         return 0;
2011 }
2012
2013 /**
2014  * \brief Silence one or more areas
2015  * \param dst_areas areas specification (one for each channel)
2016  * \param dst_offset offset in frames inside area
2017  * \param channels channels count
2018  * \param frames frames to silence
2019  * \param format PCM sample format
2020  * \return 0 on success otherwise a negative error code
2021  */
2022 int snd_pcm_areas_silence(const snd_pcm_channel_area_t *dst_areas, snd_pcm_uframes_t dst_offset,
2023                           unsigned int channels, snd_pcm_uframes_t frames, snd_pcm_format_t format)
2024 {
2025         int width = snd_pcm_format_physical_width(format);
2026         while (channels > 0) {
2027                 void *addr = dst_areas->addr;
2028                 unsigned int step = dst_areas->step;
2029                 const snd_pcm_channel_area_t *begin = dst_areas;
2030                 int channels1 = channels;
2031                 unsigned int chns = 0;
2032                 int err;
2033                 while (1) {
2034                         channels1--;
2035                         chns++;
2036                         dst_areas++;
2037                         if (channels1 == 0 ||
2038                             dst_areas->addr != addr ||
2039                             dst_areas->step != step ||
2040                             dst_areas->first != dst_areas[-1].first + width)
2041                                 break;
2042                 }
2043                 if (chns > 1 && chns * width == step) {
2044                         /* Collapse the areas */
2045                         snd_pcm_channel_area_t d;
2046                         d.addr = begin->addr;
2047                         d.first = begin->first;
2048                         d.step = width;
2049                         err = snd_pcm_area_silence(&d, dst_offset * chns, frames * chns, format);
2050                         channels -= chns;
2051                 } else {
2052                         err = snd_pcm_area_silence(begin, dst_offset, frames, format);
2053                         dst_areas = begin + 1;
2054                         channels--;
2055                 }
2056                 if (err < 0)
2057                         return err;
2058         }
2059         return 0;
2060 }
2061
2062
2063 /**
2064  * \brief Copy an area
2065  * \param dst_area destination area specification
2066  * \param dst_offset offset in frames inside destination area
2067  * \param src_area source area specification
2068  * \param src_offset offset in frames inside source area
2069  * \param samples samples to copy
2070  * \param format PCM sample format
2071  * \return 0 on success otherwise a negative error code
2072  */
2073 int snd_pcm_area_copy(const snd_pcm_channel_area_t *dst_area, snd_pcm_uframes_t dst_offset,
2074                       const snd_pcm_channel_area_t *src_area, snd_pcm_uframes_t src_offset,
2075                       unsigned int samples, snd_pcm_format_t format)
2076 {
2077         /* FIXME: sub byte resolution and odd dst_offset */
2078         const char *src;
2079         char *dst;
2080         int width;
2081         int src_step, dst_step;
2082         if (!src_area->addr)
2083                 return snd_pcm_area_silence(dst_area, dst_offset, samples, format);
2084         src = snd_pcm_channel_area_addr(src_area, src_offset);
2085         if (!dst_area->addr)
2086                 return 0;
2087         dst = snd_pcm_channel_area_addr(dst_area, dst_offset);
2088         width = snd_pcm_format_physical_width(format);
2089         if (src_area->step == (unsigned int) width &&
2090             dst_area->step == (unsigned int) width) {
2091                 size_t bytes = samples * width / 8;
2092                 samples -= bytes * 8 / width;
2093                 memcpy(dst, src, bytes);
2094                 if (samples == 0)
2095                         return 0;
2096         }
2097         src_step = src_area->step / 8;
2098         dst_step = dst_area->step / 8;
2099         switch (width) {
2100         case 4: {
2101                 int srcbit = src_area->first % 8;
2102                 int srcbit_step = src_area->step % 8;
2103                 int dstbit = dst_area->first % 8;
2104                 int dstbit_step = dst_area->step % 8;
2105                 while (samples-- > 0) {
2106                         unsigned char srcval;
2107                         if (srcbit)
2108                                 srcval = *src & 0x0f;
2109                         else
2110                                 srcval = *src & 0xf0;
2111                         if (dstbit)
2112                                 *dst &= 0xf0;
2113                         else
2114                                 *dst &= 0x0f;
2115                         *dst |= srcval;
2116                         src += src_step;
2117                         srcbit += srcbit_step;
2118                         if (srcbit == 8) {
2119                                 src++;
2120                                 srcbit = 0;
2121                         }
2122                         dst += dst_step;
2123                         dstbit += dstbit_step;
2124                         if (dstbit == 8) {
2125                                 dst++;
2126                                 dstbit = 0;
2127                         }
2128                 }
2129                 break;
2130         }
2131         case 8: {
2132                 while (samples-- > 0) {
2133                         *dst = *src;
2134                         src += src_step;
2135                         dst += dst_step;
2136                 }
2137                 break;
2138         }
2139         case 16: {
2140                 while (samples-- > 0) {
2141                         *(u_int16_t*)dst = *(const u_int16_t*)src;
2142                         src += src_step;
2143                         dst += dst_step;
2144                 }
2145                 break;
2146         }
2147         case 32: {
2148                 while (samples-- > 0) {
2149                         *(u_int32_t*)dst = *(const u_int32_t*)src;
2150                         src += src_step;
2151                         dst += dst_step;
2152                 }
2153                 break;
2154         }
2155         case 64: {
2156                 while (samples-- > 0) {
2157                         *(u_int64_t*)dst = *(const u_int64_t*)src;
2158                         src += src_step;
2159                         dst += dst_step;
2160                 }
2161                 break;
2162         }
2163         default:
2164                 assert(0);
2165         }
2166         return 0;
2167 }
2168
2169 /**
2170  * \brief Copy one or more areas
2171  * \param dst_areas destination areas specification (one for each channel)
2172  * \param dst_offset offset in frames inside destination area
2173  * \param src_areas source areas specification (one for each channel)
2174  * \param src_offset offset in frames inside source area
2175  * \param channels channels count
2176  * \param frames frames to copy
2177  * \param format PCM sample format
2178  * \return 0 on success otherwise a negative error code
2179  */
2180 int snd_pcm_areas_copy(const snd_pcm_channel_area_t *dst_areas, snd_pcm_uframes_t dst_offset,
2181                        const snd_pcm_channel_area_t *src_areas, snd_pcm_uframes_t src_offset,
2182                        unsigned int channels, snd_pcm_uframes_t frames, snd_pcm_format_t format)
2183 {
2184         int width = snd_pcm_format_physical_width(format);
2185         assert(dst_areas);
2186         assert(src_areas);
2187         assert(channels > 0);
2188         assert(frames > 0);
2189         while (channels > 0) {
2190                 unsigned int step = src_areas->step;
2191                 void *src_addr = src_areas->addr;
2192                 const snd_pcm_channel_area_t *src_start = src_areas;
2193                 void *dst_addr = dst_areas->addr;
2194                 const snd_pcm_channel_area_t *dst_start = dst_areas;
2195                 int channels1 = channels;
2196                 unsigned int chns = 0;
2197                 while (dst_areas->step == step) {
2198                         channels1--;
2199                         chns++;
2200                         src_areas++;
2201                         dst_areas++;
2202                         if (channels1 == 0 ||
2203                             src_areas->step != step ||
2204                             src_areas->addr != src_addr ||
2205                             dst_areas->addr != dst_addr ||
2206                             src_areas->first != src_areas[-1].first + width ||
2207                             dst_areas->first != dst_areas[-1].first + width)
2208                                 break;
2209                 }
2210                 if (chns > 1 && chns * width == step) {
2211                         /* Collapse the areas */
2212                         snd_pcm_channel_area_t s, d;
2213                         s.addr = src_start->addr;
2214                         s.first = src_start->first;
2215                         s.step = width;
2216                         d.addr = dst_start->addr;
2217                         d.first = dst_start->first;
2218                         d.step = width;
2219                         snd_pcm_area_copy(&d, dst_offset * chns,
2220                                           &s, src_offset * chns, 
2221                                           frames * chns, format);
2222                         channels -= chns;
2223                 } else {
2224                         snd_pcm_area_copy(dst_start, dst_offset,
2225                                           src_start, src_offset,
2226                                           frames, format);
2227                         src_areas = src_start + 1;
2228                         dst_areas = dst_start + 1;
2229                         channels--;
2230                 }
2231         }
2232         return 0;
2233 }
2234
2235 static void dump_one_param(snd_pcm_hw_params_t *params, unsigned int k, snd_output_t *out)
2236 {
2237         snd_output_printf(out, "%s: ", snd_pcm_hw_param_name(k));
2238         snd_pcm_hw_param_dump(params, k, out);
2239         snd_output_putc(out, '\n');
2240 }
2241
2242 /**
2243  * \brief Dump a PCM hardware configuration space
2244  * \param params Configuration space
2245  * \param out Output handle
2246  * \return 0 on success otherwise a negative error code
2247  */
2248 int snd_pcm_hw_params_dump(snd_pcm_hw_params_t *params, snd_output_t *out)
2249 {
2250         unsigned int k;
2251         for (k = SND_PCM_HW_PARAM_FIRST_MASK; k <= SND_PCM_HW_PARAM_LAST_MASK; k++)
2252                 dump_one_param(params, k, out);
2253         for (k = SND_PCM_HW_PARAM_FIRST_INTERVAL; k <= SND_PCM_HW_PARAM_LAST_INTERVAL; k++)
2254                 dump_one_param(params, k, out);
2255         return 0;
2256 }
2257
2258 /**
2259  * \brief Check, if hardware supports sample-resolution mmap for given configuration
2260  * \param param Configuration space
2261  * \return Boolean value
2262  * \retval 0 Hardware doesn't support sample-resolution mmap
2263  * \retval 1 Hardware supports sample-resolution mmap
2264  */
2265 int snd_pcm_hw_params_can_mmap_sample_resolution(const snd_pcm_hw_params_t *params)
2266 {
2267         assert(params);
2268         return !!(params->info & SNDRV_PCM_INFO_MMAP_VALID);
2269 }
2270
2271 /**
2272  * \brief Check, if hardware does double buffering for start/stop for given configuration
2273  * \param param Configuration space
2274  * \return Boolean value
2275  * \retval 0 Hardware doesn't do double buffering for start/stop
2276  * \retval 1 Hardware does double buffering for start/stop
2277  */
2278 int snd_pcm_hw_params_is_double(const snd_pcm_hw_params_t *params)
2279 {
2280         assert(params);
2281         return !!(params->info & SNDRV_PCM_INFO_DOUBLE);
2282 }
2283
2284 /**
2285  * \brief Check, if hardware does double buffering for data transfers for given configuration
2286  * \param param Configuration space
2287  * \return Boolean value
2288  * \retval 0 Hardware doesn't do double buffering for data transfers
2289  * \retval 1 Hardware does double buffering for data transfers
2290  */
2291 int snd_pcm_hw_params_is_batch(const snd_pcm_hw_params_t *params)
2292 {
2293         assert(params);
2294         return !!(params->info & SNDRV_PCM_INFO_BATCH);
2295 }
2296
2297 /**
2298  * \brief Check, if hardware does block transfers for samples for given configuration
2299  * \param param Configuration space
2300  * \return Boolean value
2301  * \retval 0 Hardware doesn't block transfers
2302  * \retval 1 Hardware does block transfers
2303  */
2304 int snd_pcm_hw_params_is_block_transfer(const snd_pcm_hw_params_t *params)
2305 {
2306         assert(params);
2307         return !!(params->info & SNDRV_PCM_INFO_BLOCK_TRANSFER);
2308 }
2309
2310 /**
2311  * \brief Check, if hardware supports overrange detection
2312  * \param param Configuration space
2313  * \return Boolean value
2314  * \retval 0 Hardware doesn't support overrange detection
2315  * \retval 1 Hardware supports overrange detection
2316  */
2317 int snd_pcm_hw_params_can_overrange(const snd_pcm_hw_params_t *params)
2318 {
2319         assert(params);
2320         return !!(params->info & SNDRV_PCM_INFO_OVERRANGE);
2321 }
2322
2323 /**
2324  * \brief Check, if hardware supports pause
2325  * \param param Configuration space
2326  * \return Boolean value
2327  * \retval 0 Hardware doesn't support pause
2328  * \retval 1 Hardware supports pause
2329  */
2330 int snd_pcm_hw_params_can_pause(const snd_pcm_hw_params_t *params)
2331 {
2332         assert(params);
2333         return !!(params->info & SNDRV_PCM_INFO_PAUSE);
2334 }
2335
2336 /**
2337  * \brief Check, if hardware supports resume
2338  * \param param Configuration space
2339  * \return Boolean value
2340  * \retval 0 Hardware doesn't support resume
2341  * \retval 1 Hardware supports resume
2342  */
2343 int snd_pcm_hw_params_can_resume(const snd_pcm_hw_params_t *params)
2344 {
2345         assert(params);
2346         return !!(params->info & SNDRV_PCM_INFO_RESUME);
2347 }
2348
2349 /**
2350  * \brief Check, if hardware does half-duplex only
2351  * \param param Configuration space
2352  * \return Boolean value
2353  * \retval 0 Hardware doesn't do half-duplex
2354  * \retval 1 Hardware does half-duplex
2355  */
2356 int snd_pcm_hw_params_is_half_duplex(const snd_pcm_hw_params_t *params)
2357 {
2358         assert(params);
2359         return !!(params->info & SNDRV_PCM_INFO_HALF_DUPLEX);
2360 }
2361
2362 /**
2363  * \brief Check, if hardware does joint-duplex (playback and capture are somewhat correlated)
2364  * \param param Configuration space
2365  * \return Boolean value
2366  * \retval 0 Hardware doesn't do joint-duplex
2367  * \retval 1 Hardware does joint-duplex
2368  */
2369 int snd_pcm_hw_params_is_joint_duplex(const snd_pcm_hw_params_t *params)
2370 {
2371         assert(params);
2372         return !!(params->info & SNDRV_PCM_INFO_JOINT_DUPLEX);
2373 }
2374
2375 /**
2376  * \brief Check, if hardware supports synchronized start with sample resolution
2377  * \param param Configuration space
2378  * \return Boolean value
2379  * \retval 0 Hardware doesn't support synchronized start
2380  * \retval 1 Hardware supports synchronized start
2381  */
2382 int snd_pcm_hw_params_can_sync_start(const snd_pcm_hw_params_t *params)
2383 {
2384         assert(params);
2385         return !!(params->info & SNDRV_PCM_INFO_SYNC_START);
2386 }
2387
2388 /**
2389  * \brief Get rate exact info from a configuration space
2390  * \param params Configuration space
2391  * \param rate_num Pointer to returned rate numerator
2392  * \param rate_den Pointer to returned rate denominator
2393  * \return 0 otherwise a negative error code if the info is not available
2394  */
2395 int snd_pcm_hw_params_get_rate_numden(const snd_pcm_hw_params_t *params,
2396                                       unsigned int *rate_num, unsigned int *rate_den)
2397 {
2398         if (params->rate_den == 0)
2399                 return -EINVAL;
2400         *rate_num = params->rate_num;
2401         *rate_den = params->rate_den;
2402         return 0;
2403 }
2404
2405 /**
2406  * \brief Get sample resolution info from a configuration space
2407  * \param params Configuration space
2408  * \return signification bits in sample otherwise a negative error code if the info is not available
2409  */
2410 int snd_pcm_hw_params_get_sbits(const snd_pcm_hw_params_t *params)
2411 {
2412         if (params->msbits == 0)
2413                 return -EINVAL;
2414         return params->msbits;
2415 }
2416
2417 /**
2418  * \brief Get hard are FIFO size info from a configuration space
2419  * \param params Configuration space
2420  * \return FIFO size in frames otherwise a negative error code if the info is not available
2421  */
2422 int snd_pcm_hw_params_get_fifo_size(const snd_pcm_hw_params_t *params)
2423 {
2424         if (params->fifo_size == 0)
2425                 return -EINVAL;
2426         return params->fifo_size;
2427 }
2428
2429 /**
2430  * \brief Fill params with a full configuration space for a PCM
2431  * \param pcm PCM handle
2432  * \param params Configuration space
2433  */
2434 int snd_pcm_hw_params_any(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
2435 {
2436         _snd_pcm_hw_params_any(params);
2437         return snd_pcm_hw_refine(pcm, params);
2438 }
2439
2440 /**
2441  * \brief get size of #snd_pcm_access_mask_t
2442  * \return size in bytes
2443  */
2444 size_t snd_pcm_access_mask_sizeof()
2445 {
2446         return sizeof(snd_pcm_access_mask_t);
2447 }
2448
2449 /**
2450  * \brief allocate an empty #snd_pcm_access_mask_t using standard malloc
2451  * \param ptr returned pointer
2452  * \return 0 on success otherwise negative error code
2453  */
2454 int snd_pcm_access_mask_malloc(snd_pcm_access_mask_t **ptr)
2455 {
2456         assert(ptr);
2457         *ptr = calloc(1, sizeof(snd_pcm_access_mask_t));
2458         if (!*ptr)
2459                 return -ENOMEM;
2460         return 0;
2461 }
2462
2463 /**
2464  * \brief frees a previously allocated #snd_pcm_access_mask_t
2465  * \param pointer to object to free
2466  */
2467 void snd_pcm_access_mask_free(snd_pcm_access_mask_t *obj)
2468 {
2469         free(obj);
2470 }
2471
2472 /**
2473  * \brief copy one #snd_pcm_access_mask_t to another
2474  * \param dst pointer to destination
2475  * \param src pointer to source
2476  */
2477 void snd_pcm_access_mask_copy(snd_pcm_access_mask_t *dst, const snd_pcm_access_mask_t *src)
2478 {
2479         assert(dst && src);
2480         *dst = *src;
2481 }
2482
2483 /**
2484  * \brief reset all bits in a #snd_pcm_access_mask_t
2485  * \param mask pointer to mask
2486  */
2487 void snd_pcm_access_mask_none(snd_pcm_access_mask_t *mask)
2488 {
2489         snd_mask_none((snd_mask_t *) mask);
2490 }
2491
2492 /**
2493  * \brief set all bits in a #snd_pcm_access_mask_t
2494  * \param mask pointer to mask
2495  */
2496 void snd_pcm_access_mask_any(snd_pcm_access_mask_t *mask)
2497 {
2498         snd_mask_any((snd_mask_t *) mask);
2499 }
2500
2501 /**
2502  * \brief test the presence of an access type in a #snd_pcm_access_mask_t
2503  * \param mask pointer to mask
2504  * \param val access type
2505  */
2506 int snd_pcm_access_mask_test(const snd_pcm_access_mask_t *mask, snd_pcm_access_t val)
2507 {
2508         return snd_mask_test((const snd_mask_t *) mask, (unsigned long) val);
2509 }
2510
2511 /**
2512  * \brief test, if given a #snd_pcm_access_mask_t is empty
2513  * \param mask pointer to mask
2514  * \retval 0 not empty
2515  * \retval 1 empty
2516  */
2517 int snd_pcm_access_mask_empty(const snd_pcm_access_mask_t *mask)
2518 {
2519         return snd_mask_empty((const snd_mask_t *) mask);
2520 }
2521
2522 /**
2523  * \brief make an access type present in a #snd_pcm_access_mask_t
2524  * \param mask pointer to mask
2525  * \param val access type
2526  */
2527 void snd_pcm_access_mask_set(snd_pcm_access_mask_t *mask, snd_pcm_access_t val)
2528 {
2529         snd_mask_set((snd_mask_t *) mask, (unsigned long) val);
2530 }
2531
2532 /**
2533  * \brief make an access type missing from a #snd_pcm_access_mask_t
2534  * \param mask pointer to mask
2535  * \param val access type
2536  */
2537 void snd_pcm_access_mask_reset(snd_pcm_access_mask_t *mask, snd_pcm_access_t val)
2538 {
2539         snd_mask_reset((snd_mask_t *) mask, (unsigned long) val);
2540 }
2541
2542 /**
2543  * \brief get size of #snd_pcm_format_mask_t
2544  * \return size in bytes
2545  */
2546 size_t snd_pcm_format_mask_sizeof()
2547 {
2548         return sizeof(snd_pcm_format_mask_t);
2549 }
2550
2551 /**
2552  * \brief allocate an empty #snd_pcm_format_mask_t using standard malloc
2553  * \param ptr returned pointer
2554  * \return 0 on success otherwise negative error code
2555  */
2556 int snd_pcm_format_mask_malloc(snd_pcm_format_mask_t **ptr)
2557 {
2558         assert(ptr);
2559         *ptr = calloc(1, sizeof(snd_pcm_format_mask_t));
2560         if (!*ptr)
2561                 return -ENOMEM;
2562         return 0;
2563 }
2564
2565 /**
2566  * \brief frees a previously allocated #snd_pcm_format_mask_t
2567  * \param pointer to object to free
2568  */
2569 void snd_pcm_format_mask_free(snd_pcm_format_mask_t *obj)
2570 {
2571         free(obj);
2572 }
2573
2574 /**
2575  * \brief copy one #snd_pcm_format_mask_t to another
2576  * \param dst pointer to destination
2577  * \param src pointer to source
2578  */
2579 void snd_pcm_format_mask_copy(snd_pcm_format_mask_t *dst, const snd_pcm_format_mask_t *src)
2580 {
2581         assert(dst && src);
2582         *dst = *src;
2583 }
2584
2585 /**
2586  * \brief reset all bits in a #snd_pcm_format_mask_t
2587  * \param mask pointer to mask
2588  */
2589 void snd_pcm_format_mask_none(snd_pcm_format_mask_t *mask)
2590 {
2591         snd_mask_none((snd_mask_t *) mask);
2592 }
2593
2594 /**
2595  * \brief set all bits in a #snd_pcm_format_mask_t
2596  * \param mask pointer to mask
2597  */
2598 void snd_pcm_format_mask_any(snd_pcm_format_mask_t *mask)
2599 {
2600         snd_mask_any((snd_mask_t *) mask);
2601 }
2602
2603 /**
2604  * \brief test the presence of a format in a #snd_pcm_format_mask_t
2605  * \param mask pointer to mask
2606  * \param val format
2607  */
2608 int snd_pcm_format_mask_test(const snd_pcm_format_mask_t *mask, snd_pcm_format_t val)
2609 {
2610         return snd_mask_test((const snd_mask_t *) mask, (unsigned long) val);
2611 }
2612
2613 /**
2614  * \brief test, if given a #snd_pcm_format_mask_t is empty
2615  * \param mask pointer to mask
2616  * \retval 0 not empty
2617  * \retval 1 empty
2618  */
2619 int snd_pcm_format_mask_empty(const snd_pcm_format_mask_t *mask)
2620 {
2621         return snd_mask_empty((const snd_mask_t *) mask);
2622 }
2623
2624 /**
2625  * \brief make a format present in a #snd_pcm_format_mask_t
2626  * \param mask pointer to mask
2627  * \param val format
2628  */
2629 void snd_pcm_format_mask_set(snd_pcm_format_mask_t *mask, snd_pcm_format_t val)
2630 {
2631         snd_mask_set((snd_mask_t *) mask, (unsigned long) val);
2632 }
2633
2634 /**
2635  * \brief make a format missing from a #snd_pcm_format_mask_t
2636  * \param mask pointer to mask
2637  * \param val format
2638  */
2639 void snd_pcm_format_mask_reset(snd_pcm_format_mask_t *mask, snd_pcm_format_t val)
2640 {
2641         snd_mask_reset((snd_mask_t *) mask, (unsigned long) val);
2642 }
2643
2644
2645 /**
2646  * \brief get size of #snd_pcm_subformat_mask_t
2647  * \return size in bytes
2648  */
2649 size_t snd_pcm_subformat_mask_sizeof()
2650 {
2651         return sizeof(snd_pcm_subformat_mask_t);
2652 }
2653
2654 /**
2655  * \brief allocate an empty #snd_pcm_subformat_mask_t using standard malloc
2656  * \param ptr returned pointer
2657  * \return 0 on success otherwise negative error code
2658  */
2659 int snd_pcm_subformat_mask_malloc(snd_pcm_subformat_mask_t **ptr)
2660 {
2661         assert(ptr);
2662         *ptr = calloc(1, sizeof(snd_pcm_subformat_mask_t));
2663         if (!*ptr)
2664                 return -ENOMEM;
2665         return 0;
2666 }
2667
2668 /**
2669  * \brief frees a previously allocated #snd_pcm_subformat_mask_t
2670  * \param pointer to object to free
2671  */
2672 void snd_pcm_subformat_mask_free(snd_pcm_subformat_mask_t *obj)
2673 {
2674         free(obj);
2675 }
2676
2677 /**
2678  * \brief copy one #snd_pcm_subformat_mask_t to another
2679  * \param dst pointer to destination
2680  * \param src pointer to source
2681  */
2682 void snd_pcm_subformat_mask_copy(snd_pcm_subformat_mask_t *dst, const snd_pcm_subformat_mask_t *src)
2683 {
2684         assert(dst && src);
2685         *dst = *src;
2686 }
2687
2688 /**
2689  * \brief reset all bits in a #snd_pcm_subformat_mask_t
2690  * \param mask pointer to mask
2691  */
2692 void snd_pcm_subformat_mask_none(snd_pcm_subformat_mask_t *mask)
2693 {
2694         snd_mask_none((snd_mask_t *) mask);
2695 }
2696
2697 /**
2698  * \brief set all bits in a #snd_pcm_subformat_mask_t
2699  * \param mask pointer to mask
2700  */
2701 void snd_pcm_subformat_mask_any(snd_pcm_subformat_mask_t *mask)
2702 {
2703         snd_mask_any((snd_mask_t *) mask);
2704 }
2705
2706 /**
2707  * \brief test the presence of a subformat in a #snd_pcm_subformat_mask_t
2708  * \param mask pointer to mask
2709  * \param val subformat
2710  */
2711 int snd_pcm_subformat_mask_test(const snd_pcm_subformat_mask_t *mask, snd_pcm_subformat_t val)
2712 {
2713         return snd_mask_test((const snd_mask_t *) mask, (unsigned long) val);
2714 }
2715
2716 /**
2717  * \brief test, if given a #snd_pcm_subformat_mask_t is empty
2718  * \param mask pointer to mask
2719  * \retval 0 not empty
2720  * \retval 1 empty
2721  */
2722 int snd_pcm_subformat_mask_empty(const snd_pcm_subformat_mask_t *mask)
2723 {
2724         return snd_mask_empty((const snd_mask_t *) mask);
2725 }
2726
2727 /**
2728  * \brief make a subformat present in a #snd_pcm_subformat_mask_t
2729  * \param mask pointer to mask
2730  * \param val subformat
2731  */
2732 void snd_pcm_subformat_mask_set(snd_pcm_subformat_mask_t *mask, snd_pcm_subformat_t val)
2733 {
2734         snd_mask_set((snd_mask_t *) mask, (unsigned long) val);
2735 }
2736
2737 /**
2738  * \brief make a subformat missing from a #snd_pcm_subformat_mask_t
2739  * \param mask pointer to mask
2740  * \param val subformat
2741  */
2742 void snd_pcm_subformat_mask_reset(snd_pcm_subformat_mask_t *mask, snd_pcm_subformat_t val)
2743 {
2744         snd_mask_reset((snd_mask_t *) mask, (unsigned long) val);
2745 }
2746
2747
2748 /**
2749  * \brief get size of #snd_pcm_hw_params_t
2750  * \return size in bytes
2751  */
2752 size_t snd_pcm_hw_params_sizeof()
2753 {
2754         return sizeof(snd_pcm_hw_params_t);
2755 }
2756
2757 /**
2758  * \brief allocate an invalid #snd_pcm_hw_params_t using standard malloc
2759  * \param ptr returned pointer
2760  * \return 0 on success otherwise negative error code
2761  */
2762 int snd_pcm_hw_params_malloc(snd_pcm_hw_params_t **ptr)
2763 {
2764         assert(ptr);
2765         *ptr = calloc(1, sizeof(snd_pcm_hw_params_t));
2766         if (!*ptr)
2767                 return -ENOMEM;
2768         return 0;
2769 }
2770
2771 /**
2772  * \brief frees a previously allocated #snd_pcm_hw_params_t
2773  * \param pointer to object to free
2774  */
2775 void snd_pcm_hw_params_free(snd_pcm_hw_params_t *obj)
2776 {
2777         free(obj);
2778 }
2779
2780 /**
2781  * \brief copy one #snd_pcm_hw_params_t to another
2782  * \param dst pointer to destination
2783  * \param src pointer to source
2784  */
2785 void snd_pcm_hw_params_copy(snd_pcm_hw_params_t *dst, const snd_pcm_hw_params_t *src)
2786 {
2787         assert(dst && src);
2788         *dst = *src;
2789 }
2790
2791
2792 /**
2793  * \brief Extract access type from a configuration space
2794  * \param params Configuration space
2795  * \param access Returned value
2796  * \return access type otherwise a negative error code if not exactly one is present
2797  *
2798  * Note: To use this function add '#define ALSA_PCM_NEW_HW_PARAMS_API' before '#include <alsa/asoundlib.h>'
2799  *       to enable this new function prototype. Using of older function with same name is deprecated.
2800  */
2801 #ifndef DOXYGEN
2802 int INTERNAL(snd_pcm_hw_params_get_access)(const snd_pcm_hw_params_t *params, snd_pcm_access_t *access)
2803 #else
2804 int snd_pcm_hw_params_get_access(const snd_pcm_hw_params_t *params, snd_pcm_access_t *access)
2805 #endif
2806 {
2807         unsigned int _val;
2808         int err = snd_pcm_hw_param_get(params, SND_PCM_HW_PARAM_ACCESS, &_val, NULL);
2809         if (err >= 0)
2810                 *access = _val;
2811         return err;
2812 }
2813
2814 /**
2815  * \brief Verify if an access type is available inside a configuration space for a PCM
2816  * \param pcm PCM handle
2817  * \param params Configuration space
2818  * \param access access type
2819  * \return 1 if available 0 otherwise
2820  */
2821 int snd_pcm_hw_params_test_access(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_t access)
2822 {
2823         return snd_pcm_hw_param_set(pcm, params, SND_TEST, SND_PCM_HW_PARAM_ACCESS, access, 0);
2824 }
2825
2826 /**
2827  * \brief Restrict a configuration space to contain only one access type
2828  * \param pcm PCM handle
2829  * \param params Configuration space
2830  * \param access access type
2831  * \return 0 otherwise a negative error code if configuration space would become empty
2832  */
2833 int snd_pcm_hw_params_set_access(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_t access)
2834 {
2835         return snd_pcm_hw_param_set(pcm, params, SND_TRY, SND_PCM_HW_PARAM_ACCESS, access, 0);
2836 }
2837
2838 /**
2839  * \brief Restrict a configuration space to contain only its first access type
2840  * \param pcm PCM handle
2841  * \param params Configuration space
2842  * \param access Returned first access type
2843  * \return 0 otherwise a negative error code
2844  *
2845  * Note: To use this function add '#define ALSA_PCM_NEW_HW_PARAMS_API' before '#include <alsa/asoundlib.h>'
2846  *       to enable this new function prototype. Using of older function with same name is deprecated.
2847  */
2848 #ifndef DOXYGEN
2849 int INTERNAL(snd_pcm_hw_params_set_access_first)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_t *access)
2850 #else
2851 int snd_pcm_hw_params_set_access_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_t *access)
2852 #endif
2853 {
2854         return snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_ACCESS, access, NULL);
2855 }
2856
2857 /**
2858  * \brief Restrict a configuration space to contain only its last access type
2859  * \param pcm PCM handle
2860  * \param params Configuration space
2861  * \param val Returned last access type
2862  * \return 0 otherwise a negative error code
2863  *
2864  * Note: To use this function add '#define ALSA_PCM_NEW_HW_PARAMS_API' before '#include <alsa/asoundlib.h>'
2865  *       to enable this new function prototype. Using of older function with same name is deprecated.
2866  */
2867 #ifndef DOXYGEN
2868 int INTERNAL(snd_pcm_hw_params_set_access_last)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_t *access)
2869 #else
2870 int snd_pcm_hw_params_set_access_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_t *access)
2871 #endif
2872 {
2873         return snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_ACCESS, access, NULL);
2874 }
2875
2876 /**
2877  * \brief Restrict a configuration space to contain only a set of access types
2878  * \param pcm PCM handle
2879  * \param params Configuration space
2880  * \param mask Access mask
2881  * \return 0 otherwise a negative error code
2882  */
2883 int snd_pcm_hw_params_set_access_mask(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_mask_t *mask)
2884 {
2885         return snd_pcm_hw_param_set_mask(pcm, params, SND_TRY, SND_PCM_HW_PARAM_ACCESS, (snd_mask_t *) mask);
2886 }
2887
2888 /**
2889  * \brief Get access mask from a configuration space
2890  * \param params Configuration space
2891  * \param mask Returned Access mask
2892  */
2893 int snd_pcm_hw_params_get_access_mask(snd_pcm_hw_params_t *params, snd_pcm_access_mask_t *mask)
2894 {
2895         if (params == NULL || mask == NULL)
2896                 return -EINVAL;
2897         snd_pcm_access_mask_copy(mask, snd_pcm_hw_param_get_mask(params, SND_PCM_HW_PARAM_ACCESS));
2898         return 0;
2899 }
2900
2901
2902 /**
2903  * \brief Extract format from a configuration space
2904  * \param params Configuration space
2905  * \param format returned format
2906  * \return format otherwise a negative error code if not exactly one is present
2907  *
2908  * Note: To use this function add '#define ALSA_PCM_NEW_HW_PARAMS_API' before '#include <alsa/asoundlib.h>'
2909  *       to enable this new function prototype. Using of older function with same name is deprecated.
2910  */
2911 #ifndef DOXYGEN
2912 int INTERNAL(snd_pcm_hw_params_get_format)(const snd_pcm_hw_params_t *params, snd_pcm_format_t *format)
2913 #else
2914 int snd_pcm_hw_params_get_format(const snd_pcm_hw_params_t *params, snd_pcm_format_t *format)
2915 #endif
2916 {
2917         return snd_pcm_hw_param_get(params, SND_PCM_HW_PARAM_FORMAT, format, NULL);
2918 }
2919
2920 /**
2921  * \brief Verify if a format is available inside a configuration space for a PCM
2922  * \param pcm PCM handle
2923  * \param params Configuration space
2924  * \param format format
2925  * \return 1 if available 0 otherwise
2926  */
2927 int snd_pcm_hw_params_test_format(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_t format)
2928 {
2929         return snd_pcm_hw_param_set(pcm, params, SND_TEST, SND_PCM_HW_PARAM_FORMAT, format, 0);
2930 }
2931
2932 /**
2933  * \brief Restrict a configuration space to contain only one format
2934  * \param pcm PCM handle
2935  * \param params Configuration space
2936  * \param format format
2937  * \return 0 otherwise a negative error code
2938  */
2939 int snd_pcm_hw_params_set_format(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_t format)
2940 {
2941         return snd_pcm_hw_param_set(pcm, params, SND_TRY, SND_PCM_HW_PARAM_FORMAT, format, 0);
2942 }
2943
2944 /**
2945  * \brief Restrict a configuration space to contain only its first format
2946  * \param pcm PCM handle
2947  * \param params Configuration space
2948  * \param format Returned first format
2949  * \return 0 otherwise a negative error code
2950  *
2951  * Note: To use this function add '#define ALSA_PCM_NEW_HW_PARAMS_API' before '#include <alsa/asoundlib.h>'
2952  *       to enable this new function prototype. Using of older function with same name is deprecated.
2953  */
2954 #ifndef DOXYGEN
2955 int INTERNAL(snd_pcm_hw_params_set_format_first)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_t *format)
2956 #else
2957 int snd_pcm_hw_params_set_format_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_t *format)
2958 #endif
2959 {
2960         return snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_FORMAT, format, NULL);
2961 }
2962
2963 /**
2964  * \brief Restrict a configuration space to contain only its last format
2965  * \param pcm PCM handle
2966  * \param params Configuration space
2967  * \param format Returned last format
2968  * \return 0 otherwise a negative error code
2969  *
2970  * Note: To use this function add '#define ALSA_PCM_NEW_HW_PARAMS_API' before '#include <alsa/asoundlib.h>'
2971  *       to enable this new function prototype. Using of older function with same name is deprecated.
2972  */
2973 #ifndef DOXYGEN
2974 int INTERNAL(snd_pcm_hw_params_set_format_last)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_t *format)
2975 #else
2976 int snd_pcm_hw_params_set_format_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_t *format)
2977 #endif
2978 {
2979         return snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_FORMAT, format, NULL);
2980 }
2981
2982 /**
2983  * \brief Restrict a configuration space to contain only a set of formats
2984  * \param pcm PCM handle
2985  * \param params Configuration space
2986  * \param mask Format mask
2987  * \return 0 otherwise a negative error code
2988  */
2989 int snd_pcm_hw_params_set_format_mask(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_mask_t *mask)
2990 {
2991         return snd_pcm_hw_param_set_mask(pcm, params, SND_TRY, SND_PCM_HW_PARAM_FORMAT, (snd_mask_t *) mask);
2992 }
2993
2994 /**
2995  * \brief Get format mask from a configuration space
2996  * \param params Configuration space
2997  * \param mask Returned Format mask
2998  */
2999 void snd_pcm_hw_params_get_format_mask(snd_pcm_hw_params_t *params, snd_pcm_format_mask_t *mask)
3000 {
3001         snd_pcm_format_mask_copy(mask, snd_pcm_hw_param_get_mask(params, SND_PCM_HW_PARAM_FORMAT));
3002 }
3003
3004
3005 /**
3006  * \brief Extract subformat from a configuration space
3007  * \param params Configuration space
3008  * \param subformat Returned subformat value
3009  * \return subformat otherwise a negative error code if not exactly one is present
3010  *
3011  * Note: To use this function add '#define ALSA_PCM_NEW_HW_PARAMS_API' before '#include <alsa/asoundlib.h>'
3012  *       to enable this new function prototype. Using of older function with same name is deprecated.
3013  */
3014 #ifndef DOXYGEN
3015 int INTERNAL(snd_pcm_hw_params_get_subformat)(const snd_pcm_hw_params_t *params, snd_pcm_subformat_t *subformat)
3016 #else
3017 int snd_pcm_hw_params_get_subformat(const snd_pcm_hw_params_t *params, snd_pcm_subformat_t *subformat)
3018 #endif
3019 {
3020         return snd_pcm_hw_param_get(params, SND_PCM_HW_PARAM_SUBFORMAT, subformat, NULL);
3021 }
3022
3023 /**
3024  * \brief Verify if a subformat is available inside a configuration space for a PCM
3025  * \param pcm PCM handle
3026  * \param params Configuration space
3027  * \param subformat subformat value
3028  * \return 1 if available 0 otherwise
3029  */
3030 int snd_pcm_hw_params_test_subformat(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_t subformat)
3031 {
3032         return snd_pcm_hw_param_set(pcm, params, SND_TEST, SND_PCM_HW_PARAM_SUBFORMAT, subformat, 0);
3033 }
3034
3035 /**
3036  * \brief Restrict a configuration space to contain only one subformat
3037  * \param pcm PCM handle
3038  * \param params Configuration space
3039  * \param subformat subformat value
3040  * \return 0 otherwise a negative error code if configuration space would become empty
3041  */
3042 int snd_pcm_hw_params_set_subformat(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_t subformat)
3043 {
3044         return snd_pcm_hw_param_set(pcm, params, SND_TRY, SND_PCM_HW_PARAM_SUBFORMAT, subformat, 0);
3045 }
3046
3047 /**
3048  * \brief Restrict a configuration space to contain only its first subformat
3049  * \param pcm PCM handle
3050  * \param params Configuration space
3051  * \param subformat Returned subformat
3052  * \return 0 otherwise a negative error code
3053  *
3054  * Note: To use this function add '#define ALSA_PCM_NEW_HW_PARAMS_API' before '#include <alsa/asoundlib.h>'
3055  *       to enable this new function prototype. Using of older function with same name is deprecated.
3056  */
3057 #ifndef DOXYGEN
3058 int INTERNAL(snd_pcm_hw_params_set_subformat_first)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_t *subformat)
3059 #else
3060 int snd_pcm_hw_params_set_subformat_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_t *subformat)
3061 #endif
3062 {
3063         return snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_SUBFORMAT, subformat, NULL);
3064 }
3065
3066 /**
3067  * \brief Restrict a configuration space to contain only its last subformat
3068  * \param pcm PCM handle
3069  * \param params Configuration space
3070  * \param subformat Returned subformat
3071  * \return 0 otherwise a negative error code
3072  *
3073  * Note: To use this function add '#define ALSA_PCM_NEW_HW_PARAMS_API' before '#include <alsa/asoundlib.h>'
3074  *       to enable this new function prototype. Using of older function with same name is deprecated.
3075  */
3076 #ifndef DOXYGEN
3077 int INTERNAL(snd_pcm_hw_params_set_subformat_last)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_t *subformat)
3078 #else
3079 int snd_pcm_hw_params_set_subformat_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_t *subformat)
3080 #endif
3081 {
3082         return snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_SUBFORMAT, subformat, NULL);
3083 }
3084
3085 /**
3086  * \brief Restrict a configuration space to contain only a set of subformats
3087  * \param pcm PCM handle
3088  * \param params Configuration space
3089  * \param mask Subformat mask
3090  * \return 0 otherwise a negative error code
3091  */
3092 int snd_pcm_hw_params_set_subformat_mask(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_mask_t *mask)
3093 {
3094         return snd_pcm_hw_param_set_mask(pcm, params, SND_TRY, SND_PCM_HW_PARAM_SUBFORMAT, (snd_mask_t *) mask);
3095 }
3096
3097 /**
3098  * \brief Get subformat mask from a configuration space
3099  * \param params Configuration space
3100  * \param mask Returned Subformat mask
3101  */
3102 void snd_pcm_hw_params_get_subformat_mask(snd_pcm_hw_params_t *params, snd_pcm_subformat_mask_t *mask)
3103 {
3104         snd_pcm_subformat_mask_copy(mask, snd_pcm_hw_param_get_mask(params, SND_PCM_HW_PARAM_SUBFORMAT));
3105 }
3106
3107
3108 /**
3109  * \brief Extract channels from a configuration space
3110  * \param params Configuration space
3111  * \param val Returned channels count
3112  * \return 0 otherwise a negative error code if not exactly one is present
3113  *
3114  * Note: To use this function add '#define ALSA_PCM_NEW_HW_PARAMS_API' before '#include <alsa/asoundlib.h>'
3115  *       to enable this new function prototype. Using of older function with same name is deprecated.
3116  */
3117 #ifndef DOXYGEN
3118 int INTERNAL(snd_pcm_hw_params_get_channels)(const snd_pcm_hw_params_t *params, unsigned int *val)
3119 #else
3120 int snd_pcm_hw_params_get_channels(const snd_pcm_hw_params_t *params, unsigned int *val)
3121 #endif
3122 {
3123         return snd_pcm_hw_param_get(params, SND_PCM_HW_PARAM_CHANNELS, val, NULL);
3124 }
3125
3126 /**
3127  * \brief Extract minimum channels count from a configuration space
3128  * \param params Configuration space
3129  * \param val minimum channels count
3130  * \return 0 otherwise a negative error code
3131  *
3132  * Note: To use this function add '#define ALSA_PCM_NEW_HW_PARAMS_API' before '#include <alsa/asoundlib.h>'
3133  *       to enable this new function prototype. Using of older function with same name is deprecated.
3134  */
3135 #ifndef DOXYGEN
3136 int INTERNAL(snd_pcm_hw_params_get_channels_min)(const snd_pcm_hw_params_t *params, unsigned int *val)
3137 #else
3138 int snd_pcm_hw_params_get_channels_min(const snd_pcm_hw_params_t *params, unsigned int *val)
3139 #endif
3140 {
3141         return snd_pcm_hw_param_get_min(params, SND_PCM_HW_PARAM_CHANNELS, val, NULL);
3142 }
3143
3144 /**
3145  * \brief Extract maximum channels count from a configuration space
3146  * \param params Configuration space
3147  * \param val maximum channels count
3148  * \return 0 otherwise a negative error code
3149  *
3150  * Note: To use this function add '#define ALSA_PCM_NEW_HW_PARAMS_API' before '#include <alsa/asoundlib.h>'
3151  *       to enable this new function prototype. Using of older function with same name is deprecated.
3152  */
3153 #ifndef DOXYGEN
3154 int INTERNAL(snd_pcm_hw_params_get_channels_max)(const snd_pcm_hw_params_t *params, unsigned int *val)
3155 #else
3156 int snd_pcm_hw_params_get_channels_max(const snd_pcm_hw_params_t *params, unsigned int *val)
3157 #endif
3158 {
3159         return snd_pcm_hw_param_get_max(params, SND_PCM_HW_PARAM_CHANNELS, val, NULL);
3160 }
3161
3162 /**
3163  * \brief Verify if a channels count is available inside a configuration space for a PCM
3164  * \param pcm PCM handle
3165  * \param params Configuration space
3166  * \param val channels count
3167  * \return 1 if available 0 otherwise
3168  */
3169 int snd_pcm_hw_params_test_channels(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val)
3170 {
3171         return snd_pcm_hw_param_set(pcm, params, SND_TEST, SND_PCM_HW_PARAM_CHANNELS, val, 0);
3172 }
3173
3174 /**
3175  * \brief Restrict a configuration space to contain only one channels count
3176  * \param pcm PCM handle
3177  * \param params Configuration space
3178  * \param val channels count
3179  * \return 0 otherwise a negative error code if configuration space would become empty
3180  */
3181 int snd_pcm_hw_params_set_channels(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val)
3182 {
3183         return snd_pcm_hw_param_set(pcm, params, SND_TRY, SND_PCM_HW_PARAM_CHANNELS, val, 0);
3184 }
3185
3186 /**
3187  * \brief Restrict a configuration space with a minimum channels count
3188  * \param pcm PCM handle
3189  * \param params Configuration space
3190  * \param val minimum channels count (on return filled with actual minimum)
3191  * \return 0 otherwise a negative error code if configuration space would become empty
3192  */
3193 int snd_pcm_hw_params_set_channels_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val)
3194 {
3195         return snd_pcm_hw_param_set_min(pcm, params, SND_TRY, SND_PCM_HW_PARAM_CHANNELS, val, NULL);
3196 }
3197
3198 /**
3199  * \brief Restrict a configuration space with a maximum channels count
3200  * \param pcm PCM handle
3201  * \param params Configuration space
3202  * \param val maximum channels count (on return filled with actual maximum)
3203  * \return 0 otherwise a negative error code if configuration space would become empty
3204  */
3205 int snd_pcm_hw_params_set_channels_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val)
3206 {
3207         return snd_pcm_hw_param_set_max(pcm, params, SND_TRY, SND_PCM_HW_PARAM_CHANNELS, val, NULL);
3208 }
3209
3210 /**
3211  * \brief Restrict a configuration space to have channels counts in a given range
3212  * \param pcm PCM handle
3213  * \param params Configuration space
3214  * \param min minimum channels count (on return filled with actual minimum)
3215  * \param max maximum channels count (on return filled with actual maximum)
3216  * \return 0 otherwise a negative error code if configuration space would become empty
3217  */
3218 int snd_pcm_hw_params_set_channels_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *min, unsigned int *max)
3219 {
3220         return snd_pcm_hw_param_set_minmax(pcm, params, SND_TRY, SND_PCM_HW_PARAM_CHANNELS, min, NULL, max, NULL);
3221 }
3222
3223 /**
3224  * \brief Restrict a configuration space to have channels count nearest to a target
3225  * \param pcm PCM handle
3226  * \param params Configuration space
3227  * \param val target channels count, returned chosen channels count
3228  * \return chosen channels count
3229  *
3230  * Note: To use this function add '#define ALSA_PCM_NEW_HW_PARAMS_API' before '#include <alsa/asoundlib.h>'
3231  *       to enable this new function prototype. Using of older function with same name is deprecated.
3232  */
3233 #ifndef DOXYGEN
3234 int INTERNAL(snd_pcm_hw_params_set_channels_near)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val)
3235 #else
3236 int snd_pcm_hw_params_set_channels_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val)
3237 #endif
3238 {
3239         return snd_pcm_hw_param_set_near(pcm, params, SND_PCM_HW_PARAM_CHANNELS, val, NULL);
3240 }
3241
3242 /**
3243  * \brief Restrict a configuration space to contain only its minimum channels count
3244  * \param pcm PCM handle
3245  * \param params Configuration space
3246  * \param val minimum channels count
3247  * \return 0 otherwise a negative error code
3248  *
3249  * Note: To use this function add '#define ALSA_PCM_NEW_HW_PARAMS_API' before '#include <alsa/asoundlib.h>'
3250  *       to enable this new function prototype. Using of older function with same name is deprecated.
3251  */
3252 #ifndef DOXYGEN
3253 int INTERNAL(snd_pcm_hw_params_set_channels_first)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val)
3254 #else
3255 int snd_pcm_hw_params_set_channels_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val)
3256 #endif
3257 {
3258         return snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_CHANNELS, val, NULL);
3259 }
3260
3261 /**
3262  * \brief Restrict a configuration space to contain only its maximum channels count
3263  * \param pcm PCM handle
3264  * \param params Configuration space
3265  * \param val maximum channels count
3266  * \return 0 otherwise a negative error code
3267  *
3268  * Note: To use this function add '#define ALSA_PCM_NEW_HW_PARAMS_API' before '#include <alsa/asoundlib.h>'
3269  *       to enable this new function prototype. Using of older function with same name is deprecated.
3270  */
3271 #ifndef DOXYGEN
3272 int INTERNAL(snd_pcm_hw_params_set_channels_last)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val)
3273 #else
3274 int snd_pcm_hw_params_set_channels_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val)
3275 #endif
3276 {
3277         return snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_CHANNELS, val, NULL);
3278 }
3279
3280
3281 /**
3282  * \brief Extract rate from a configuration space
3283  * \param params Configuration space
3284  * \param val Returned approximate rate
3285  * \param dir Sub unit direction
3286  * \return 0 otherwise a negative error code if not exactly one is present
3287  *
3288  * Actual exact value is <,=,> the approximate one following dir (-1, 0, 1)
3289  *
3290  * Note: To use this function add '#define ALSA_PCM_NEW_HW_PARAMS_API' before '#include <alsa/asoundlib.h>'
3291  *       to enable this new function prototype. Using of older function with same name is deprecated.
3292  */
3293 #ifndef DOXYGEN
3294 int INTERNAL(snd_pcm_hw_params_get_rate)(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
3295 #else
3296 int snd_pcm_hw_params_get_rate(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
3297 #endif
3298 {
3299         return snd_pcm_hw_param_get(params, SND_PCM_HW_PARAM_RATE, val, dir);
3300 }
3301
3302 /**
3303  * \brief Extract minimum rate from a configuration space
3304  * \param params Configuration space
3305  * \param val Returned approximate minimum rate
3306  * \param dir Sub unit direction
3307  * \return 0 otherwise a negative error code
3308  *
3309  * Exact value is <,=,> the returned one following dir (-1,0,1)
3310  *
3311  * Note: To use this function add '#define ALSA_PCM_NEW_HW_PARAMS_API' before '#include <alsa/asoundlib.h>'
3312  *       to enable this new function prototype. Using of older function with same name is deprecated.
3313  */
3314 #ifndef DOXYGEN
3315 int INTERNAL(snd_pcm_hw_params_get_rate_min)(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
3316 #else
3317 int snd_pcm_hw_params_get_rate_min(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
3318 #endif
3319 {
3320         return snd_pcm_hw_param_get_min(params, SND_PCM_HW_PARAM_RATE, val, dir);
3321 }
3322
3323 /**
3324  * \brief Extract maximum rate from a configuration space
3325  * \param params Configuration space
3326  * \param val Returned approximate maximum rate
3327  * \param dir Sub unit direction
3328  * \return 0 otherwise a negative error code
3329  *
3330  * Exact value is <,=,> the returned one following dir (-1,0,1)
3331  *
3332  * Note: To use this function add '#define ALSA_PCM_NEW_HW_PARAMS_API' before '#include <alsa/asoundlib.h>'
3333  *       to enable this new function prototype. Using of older function with same name is deprecated.
3334  */
3335 #ifndef DOXYGEN
3336 int INTERNAL(snd_pcm_hw_params_get_rate_max)(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
3337 #else
3338 int snd_pcm_hw_params_get_rate_max(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
3339 #endif
3340 {
3341         return snd_pcm_hw_param_get_max(params, SND_PCM_HW_PARAM_RATE, val, dir);
3342 }
3343
3344 /**
3345  * \brief Verify if a rate is available inside a configuration space for a PCM
3346  * \param pcm PCM handle
3347  * \param params Configuration space
3348  * \param val approximate rate
3349  * \param dir Sub unit direction
3350  * \return 1 if available 0 otherwise
3351  *
3352  * Wanted exact value is <,=,> val following dir (-1,0,1)
3353  */
3354 int snd_pcm_hw_params_test_rate(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir)
3355 {
3356         return snd_pcm_hw_param_set(pcm, params, SND_TEST, SND_PCM_HW_PARAM_RATE, val, dir);
3357 }
3358
3359 /**
3360  * \brief Restrict a configuration space to contain only one rate
3361  * \param pcm PCM handle
3362  * \param params Configuration space
3363  * \param val approximate rate
3364  * \param dir Sub unit direction
3365  * \return 0 otherwise a negative error code if configuration space would become empty
3366  *
3367  * Wanted exact value is <,=,> val following dir (-1,0,1)
3368  */
3369 int snd_pcm_hw_params_set_rate(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir)
3370 {
3371         return snd_pcm_hw_param_set(pcm, params, SND_TRY, SND_PCM_HW_PARAM_RATE, val, dir);
3372 }
3373
3374 /**
3375  * \brief Restrict a configuration space with a minimum rate
3376  * \param pcm PCM handle
3377  * \param params Configuration space
3378  * \param val approximate minimum rate (on return filled with actual minimum)
3379  * \param dir Sub unit direction (on return filled with actual direction)
3380  * \return 0 otherwise a negative error code if configuration space would become empty
3381  *
3382  * Wanted/actual exact minimum is <,=,> val following dir (-1,0,1)
3383  */
3384 int snd_pcm_hw_params_set_rate_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
3385 {
3386         return snd_pcm_hw_param_set_min(pcm, params, SND_TRY, SND_PCM_HW_PARAM_RATE, val, dir);
3387 }
3388
3389 /**
3390  * \brief Restrict a configuration space with a maximum rate
3391  * \param pcm PCM handle
3392  * \param params Configuration space
3393  * \param val approximate maximum rate (on return filled with actual maximum)
3394  * \param dir Sub unit direction (on return filled with actual direction)
3395  * \return 0 otherwise a negative error code if configuration space would become empty
3396  *
3397  * Wanted/actual exact maximum is <,=,> val following dir (-1,0,1)
3398  */
3399 int snd_pcm_hw_params_set_rate_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
3400 {
3401         return snd_pcm_hw_param_set_max(pcm, params, SND_TRY, SND_PCM_HW_PARAM_RATE, val, dir);
3402 }
3403
3404 /**
3405  * \brief Restrict a configuration space to have rates in a given range
3406  * \param pcm PCM handle
3407  * \param params Configuration space
3408  * \param min approximate minimum rate (on return filled with actual minimum)
3409  * \param mindir Sub unit direction for minimum (on return filled with actual direction)
3410  * \param max approximate maximum rate (on return filled with actual maximum)
3411  * \param maxdir Sub unit direction for maximum (on return filled with actual direction)
3412  * \return 0 otherwise a negative error code if configuration space would become empty
3413  *
3414  * Wanted/actual exact min/max is <,=,> val following dir (-1,0,1)
3415  */
3416 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)
3417 {
3418         return snd_pcm_hw_param_set_minmax(pcm, params, SND_TRY, SND_PCM_HW_PARAM_RATE, min, mindir, max, maxdir);
3419 }
3420
3421 /**
3422  * \brief Restrict a configuration space to have rate nearest to a target
3423  * \param pcm PCM handle
3424  * \param params Configuration space
3425  * \param val approximate target rate / returned approximate set rate
3426  * \return approximate chosen rate
3427  *
3428  * target/chosen exact value is <,=,> val following dir (-1,0,1)
3429  *
3430  * Note: To use this function add '#define ALSA_PCM_NEW_HW_PARAMS_API' before '#include <alsa/asoundlib.h>'
3431  *       to enable this new function prototype. Using of older function with same name is deprecated.
3432  */
3433 #ifndef DOXYGEN
3434 int INTERNAL(snd_pcm_hw_params_set_rate_near)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
3435 #else
3436 int snd_pcm_hw_params_set_rate_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
3437 #endif
3438 {
3439         return snd_pcm_hw_param_set_near(pcm, params, SND_PCM_HW_PARAM_RATE, val, dir);
3440 }
3441
3442 /**
3443  * \brief Restrict a configuration space to contain only its minimum rate
3444  * \param pcm PCM handle
3445  * \param params Configuration space
3446  * \param val Returned minimum approximate rate
3447  * \param dir Sub unit direction
3448  * \return 0 otherwise a negative error code
3449  *
3450  * Actual exact value is <,=,> the approximate one following dir (-1, 0, 1)
3451  *
3452  * Note: To use this function add '#define ALSA_PCM_NEW_HW_PARAMS_API' before '#include <alsa/asoundlib.h>'
3453  *       to enable this new function prototype. Using of older function with same name is deprecated.
3454  */
3455 #ifndef DOXYGEN
3456 int INTERNAL(snd_pcm_hw_params_set_rate_first)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
3457 #else
3458 int snd_pcm_hw_params_set_rate_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
3459 #endif
3460 {
3461         return snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_RATE, val, dir);
3462 }
3463
3464 /**
3465  * \brief Restrict a configuration space to contain only its maximum rate
3466  * \param pcm PCM handle
3467  * \param params Configuration space
3468  * \param val Returned maximum approximate rate
3469  * \param dir Sub unit direction
3470  * \return 0 otherwise a negative error code
3471  *
3472  * Actual exact value is <,=,> the approximate one following dir (-1, 0, 1)
3473  *
3474  * Note: To use this function add '#define ALSA_PCM_NEW_HW_PARAMS_API' before '#include <alsa/asoundlib.h>'
3475  *       to enable this new function prototype. Using of older function with same name is deprecated.
3476  */
3477 #ifndef DOXYGEN
3478 int INTERNAL(snd_pcm_hw_params_set_rate_last)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
3479 #else
3480 int snd_pcm_hw_params_set_rate_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
3481 #endif
3482 {
3483         return snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_RATE, val, dir);
3484 }
3485
3486
3487 /**
3488  * \brief Extract period time from a configuration space
3489  * \param params Configuration space
3490  * \param val Returned approximate period duration in us
3491  * \param dir Sub unit direction
3492  * \return 0 otherwise a negative error code if not exactly one is present
3493  *
3494  * Actual exact value is <,=,> the approximate one following dir (-1, 0, 1)
3495  *
3496  * Note: To use this function add '#define ALSA_PCM_NEW_HW_PARAMS_API' before '#include <alsa/asoundlib.h>'
3497  *       to enable this new function prototype. Using of older function with same name is deprecated.
3498  */
3499 #ifndef DOXYGEN
3500 int INTERNAL(snd_pcm_hw_params_get_period_time)(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
3501 #else
3502 int snd_pcm_hw_params_get_period_time(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
3503 #endif
3504 {
3505         return snd_pcm_hw_param_get(params, SND_PCM_HW_PARAM_PERIOD_TIME, val, dir);
3506 }
3507
3508 /**
3509  * \brief Extract minimum period time from a configuration space
3510  * \param params Configuration space
3511  * \param val approximate minimum period duration in us
3512  * \param dir Sub unit direction
3513  * \return 0 otherwise a negative error code
3514  *
3515  * Exact value is <,=,> the returned one following dir (-1,0,1)
3516  *
3517  * Note: To use this function add '#define ALSA_PCM_NEW_HW_PARAMS_API' before '#include <alsa/asoundlib.h>'
3518  *       to enable this new function prototype. Using of older function with same name is deprecated.
3519  */
3520 #ifndef DOXYGEN
3521 int INTERNAL(snd_pcm_hw_params_get_period_time_min)(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
3522 #else
3523 int snd_pcm_hw_params_get_period_time_min(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
3524 #endif
3525 {
3526         return snd_pcm_hw_param_get_min(params, SND_PCM_HW_PARAM_PERIOD_TIME, val, dir);
3527 }
3528
3529 /**
3530  * \brief Extract maximum period time from a configuration space
3531  * \param params Configuration space
3532  * \param val approximate maximum period duration in us
3533  * \param dir Sub unit direction
3534  * \return 0 otherwise a negative error code
3535  *
3536  * Exact value is <,=,> the returned one following dir (-1,0,1)
3537  *
3538  * Note: To use this function add '#define ALSA_PCM_NEW_HW_PARAMS_API' before '#include <alsa/asoundlib.h>'
3539  *       to enable this new function prototype. Using of older function with same name is deprecated.
3540  */
3541 #ifndef DOXYGEN
3542 int INTERNAL(snd_pcm_hw_params_get_period_time_max)(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
3543 #else
3544 int snd_pcm_hw_params_get_period_time_max(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
3545 #endif
3546 {
3547         return snd_pcm_hw_param_get_max(params, SND_PCM_HW_PARAM_PERIOD_TIME, val, dir);
3548 }
3549
3550 /**
3551  * \brief Verify if a period time is available inside a configuration space for a PCM
3552  * \param pcm PCM handle
3553  * \param params Configuration space
3554  * \param val approximate period duration in us
3555  * \param dir Sub unit direction
3556  * \return 1 if available 0 otherwise
3557  *
3558  * Wanted exact value is <,=,> val following dir (-1,0,1)
3559  */
3560 int snd_pcm_hw_params_test_period_time(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir)
3561 {
3562         return snd_pcm_hw_param_set(pcm, params, SND_TEST, SND_PCM_HW_PARAM_PERIOD_TIME, val, dir);
3563 }
3564
3565 /**
3566  * \brief Restrict a configuration space to contain only one period time
3567  * \param pcm PCM handle
3568  * \param params Configuration space
3569  * \param val approximate period duration in us
3570  * \param dir Sub unit direction
3571  * \return 0 otherwise a negative error code if configuration space would become empty
3572  *
3573  * Wanted exact value is <,=,> val following dir (-1,0,1)
3574  */
3575 int snd_pcm_hw_params_set_period_time(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir)
3576 {
3577         return snd_pcm_hw_param_set(pcm, params, SND_TRY, SND_PCM_HW_PARAM_PERIOD_TIME, val, dir);
3578 }
3579
3580
3581 /**
3582  * \brief Restrict a configuration space with a minimum period time
3583  * \param pcm PCM handle
3584  * \param params Configuration space
3585  * \param val approximate minimum period duration in us (on return filled with actual minimum)
3586  * \param dir Sub unit direction (on return filled with actual direction)
3587  * \return 0 otherwise a negative error code if configuration space would become empty
3588  *
3589  * Wanted/actual exact minimum is <,=,> val following dir (-1,0,1)
3590  */
3591 int snd_pcm_hw_params_set_period_time_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
3592 {
3593         return snd_pcm_hw_param_set_min(pcm, params, SND_TRY, SND_PCM_HW_PARAM_PERIOD_TIME, val, dir);
3594 }
3595
3596 /**
3597  * \brief Restrict a configuration space with a maximum period time
3598  * \param pcm PCM handle
3599  * \param params Configuration space
3600  * \param val approximate maximum period duration in us (on return filled with actual maximum)
3601  * \param dir Sub unit direction (on return filled with actual direction)
3602  * \return 0 otherwise a negative error code if configuration space would become empty
3603  *
3604  * Wanted/actual exact maximum is <,=,> val following dir (-1,0,1)
3605  */
3606 int snd_pcm_hw_params_set_period_time_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
3607 {
3608         return snd_pcm_hw_param_set_max(pcm, params, SND_TRY, SND_PCM_HW_PARAM_PERIOD_TIME, val, dir);
3609 }
3610
3611 /**
3612  * \brief Restrict a configuration space to have period times in a given range
3613  * \param pcm PCM handle
3614  * \param params Configuration space
3615  * \param min approximate minimum period duration in us (on return filled with actual minimum)
3616  * \param mindir Sub unit direction for minimum (on return filled with actual direction)
3617  * \param max approximate maximum period duration in us (on return filled with actual maximum)
3618  * \param maxdir Sub unit direction for maximum (on return filled with actual direction)
3619  * \return 0 otherwise a negative error code if configuration space would become empty
3620  *
3621  * Wanted/actual exact min/max is <,=,> val following dir (-1,0,1)
3622  */
3623 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)
3624 {
3625         return snd_pcm_hw_param_set_minmax(pcm, params, SND_TRY, SND_PCM_HW_PARAM_PERIOD_TIME, min, mindir, max, maxdir);
3626 }
3627
3628 /**
3629  * \brief Restrict a configuration space to have period time nearest to a target
3630  * \param pcm PCM handle
3631  * \param params Configuration space
3632  * \param val approximate target period duration in us / returned chosen approximate target period duration
3633  * \return approximate chosen period duration in us
3634  *
3635  * target/chosen exact value is <,=,> val following dir (-1,0,1)
3636  *
3637  * Note: To use this function add '#define ALSA_PCM_NEW_HW_PARAMS_API' before '#include <alsa/asoundlib.h>'
3638  *       to enable this new function prototype. Using of older function with same name is deprecated.
3639  */
3640 #ifndef DOXYGEN
3641 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)
3642 #else
3643 int snd_pcm_hw_params_set_period_time_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
3644 #endif
3645 {
3646         return snd_pcm_hw_param_set_near(pcm, params, SND_PCM_HW_PARAM_PERIOD_TIME, val, dir);
3647 }
3648
3649 /**
3650  * \brief Restrict a configuration space to contain only its minimum period time
3651  * \param pcm PCM handle
3652  * \param params Configuration space
3653  * \param val Returned approximate period duration in us
3654  * \param dir Sub unit direction
3655  * \return 0 otherwise a negative error code
3656  *
3657  * Actual exact value is <,=,> the approximate one following dir (-1, 0, 1)
3658  *
3659  * Note: To use this function add '#define ALSA_PCM_NEW_HW_PARAMS_API' before '#include <alsa/asoundlib.h>'
3660  *       to enable this new function prototype. Using of older function with same name is deprecated.
3661  */
3662 #ifndef DOXYGEN
3663 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)
3664 #else
3665 int snd_pcm_hw_params_set_period_time_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
3666 #endif
3667 {
3668         return snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_PERIOD_TIME, val, dir);
3669 }
3670
3671 /**
3672  * \brief Restrict a configuration space to contain only its maximum period time
3673  * \param pcm PCM handle
3674  * \param params Configuration space
3675  * \param dir Sub unit direction
3676  * \return approximate period duration in us
3677  *
3678  * Actual exact value is <,=,> the approximate one following dir (-1, 0, 1)
3679  *
3680  * Note: To use this function add '#define ALSA_PCM_NEW_HW_PARAMS_API' before '#include <alsa/asoundlib.h>'
3681  *       to enable this new function prototype. Using of older function with same name is deprecated.
3682  */
3683 #ifndef DOXYGEN
3684 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)
3685 #else
3686 int snd_pcm_hw_params_set_period_time_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
3687 #endif
3688 {
3689         return snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_PERIOD_TIME, val, dir);
3690 }
3691
3692
3693 /**
3694  * \brief Extract period size from a configuration space
3695  * \param params Configuration space
3696  * \param val Returned approximate period size in frames
3697  * \param dir Sub unit direction
3698  * \return 0 otherwise a negative error code if not exactly one is present
3699  *
3700  * Actual exact value is <,=,> the approximate one following dir (-1, 0, 1)
3701  *
3702  * Note: To use this function add '#define ALSA_PCM_NEW_HW_PARAMS_API' before '#include <alsa/asoundlib.h>'
3703  *       to enable this new function prototype. Using of older function with same name is deprecated.
3704  */
3705 #ifndef DOXYGEN
3706 int INTERNAL(snd_pcm_hw_params_get_period_size)(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir)
3707 #else
3708 int snd_pcm_hw_params_get_period_size(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir)
3709 #endif
3710 {
3711         unsigned int _val;
3712         int err = snd_pcm_hw_param_get(params, SND_PCM_HW_PARAM_PERIOD_SIZE, &_val, dir);
3713         if (err >= 0)
3714                 *val = _val;
3715         return err;
3716 }
3717
3718 /**
3719  * \brief Extract minimum period size from a configuration space
3720  * \param params Configuration space
3721  * \param val approximate minimum period size in frames
3722  * \param dir Sub unit direction
3723  * \return 0 otherwise a negative error code
3724  *
3725  * Exact value is <,=,> the returned one following dir (-1,0,1)
3726  *
3727  * Note: To use this function add '#define ALSA_PCM_NEW_HW_PARAMS_API' before '#include <alsa/asoundlib.h>'
3728  *       to enable this new function prototype. Using of older function with same name is deprecated.
3729  */
3730 #ifndef DOXYGEN
3731 int INTERNAL(snd_pcm_hw_params_get_period_size_min)(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir)
3732 #else
3733 int snd_pcm_hw_params_get_period_size_min(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir)
3734 #endif
3735 {
3736         unsigned int _val = *val;
3737         int err = snd_pcm_hw_param_get_min(params, SND_PCM_HW_PARAM_PERIOD_SIZE, &_val, dir);
3738         if (err >= 0)
3739                 *val = _val;
3740         return err;
3741 }
3742
3743 /**
3744  * \brief Extract maximum period size from a configuration space
3745  * \param params Configuration space
3746  * \param val approximate minimum period size in frames
3747  * \param dir Sub unit direction
3748  * \return 0 otherwise a negative error code
3749  *
3750  * Exact value is <,=,> the returned one following dir (-1,0,1)
3751  *
3752  * Note: To use this function add '#define ALSA_PCM_NEW_HW_PARAMS_API' before '#include <alsa/asoundlib.h>'
3753  *       to enable this new function prototype. Using of older function with same name is deprecated.
3754  */
3755 #ifndef DOXYGEN
3756 int INTERNAL(snd_pcm_hw_params_get_period_size_max)(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir)
3757 #else
3758 int snd_pcm_hw_params_get_period_size_max(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir)
3759 #endif
3760 {
3761         unsigned int _val = *val;
3762         int err = snd_pcm_hw_param_get_max(params, SND_PCM_HW_PARAM_PERIOD_SIZE, &_val, dir);
3763         if (err >= 0)
3764                 *val = _val;
3765         return err;
3766 }
3767
3768 /**
3769  * \brief Verify if a period size is available inside a configuration space for a PCM
3770  * \param pcm PCM handle
3771  * \param params Configuration space
3772  * \param val approximate period size in frames
3773  * \param dir Sub unit direction
3774  * \return 1 if available 0 otherwise
3775  *
3776  * Wanted exact value is <,=,> val following dir (-1,0,1)
3777  */
3778 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)
3779 {
3780         return snd_pcm_hw_param_set(pcm, params, SND_TEST, SND_PCM_HW_PARAM_PERIOD_SIZE, val, dir);
3781 }
3782
3783 /**
3784  * \brief Restrict a configuration space to contain only one period size
3785  * \param pcm PCM handle
3786  * \param params Configuration space
3787  * \param val approximate period size in frames
3788  * \param dir Sub unit direction
3789  * \return 0 otherwise a negative error code if configuration space would become empty
3790  *
3791  * Wanted exact value is <,=,> val following dir (-1,0,1)
3792  */
3793 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)
3794 {
3795         return snd_pcm_hw_param_set(pcm, params, SND_TRY, SND_PCM_HW_PARAM_PERIOD_SIZE, val, dir);
3796 }
3797
3798 /**
3799  * \brief Restrict a configuration space with a minimum period size
3800  * \param pcm PCM handle
3801  * \param params Configuration space
3802  * \param val approximate minimum period size in frames (on return filled with actual minimum)
3803  * \param dir Sub unit direction (on return filled with actual direction)
3804  * \return 0 otherwise a negative error code if configuration space would become empty
3805  *
3806  * Wanted/actual exact minimum is <,=,> val following dir (-1,0,1)
3807  */
3808 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)
3809 {
3810         unsigned int _val = *val;
3811         int err = snd_pcm_hw_param_set_min(pcm, params, SND_TRY, SND_PCM_HW_PARAM_PERIOD_SIZE, &_val, dir);
3812         if (err >= 0)
3813                 *val = _val;
3814         return err;
3815 }
3816
3817 /**
3818  * \brief Restrict a configuration space with a maximum period size
3819  * \param pcm PCM handle
3820  * \param params Configuration space
3821  * \param val approximate maximum period size in frames (on return filled with actual maximum)
3822  * \param dir Sub unit direction (on return filled with actual direction)
3823  * \return 0 otherwise a negative error code if configuration space would become empty
3824  *
3825  * Wanted/actual exact minimum is <,=,> val following dir (-1,0,1)
3826  */
3827 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)
3828 {
3829         unsigned int _val = *val;
3830         int err = snd_pcm_hw_param_set_max(pcm, params, SND_TRY, SND_PCM_HW_PARAM_PERIOD_SIZE, &_val, dir);
3831         if (err >= 0)
3832                 *val = _val;
3833         return err;
3834 }
3835
3836 /**
3837  * \brief Restrict a configuration space to have period sizes in a given range
3838  * \param pcm PCM handle
3839  * \param params Configuration space
3840  * \param min approximate minimum period size in frames (on return filled with actual minimum)
3841  * \param mindir Sub unit direction for minimum (on return filled with actual direction)
3842  * \param max approximate maximum period size in frames (on return filled with actual maximum)
3843  * \param maxdir Sub unit direction for maximum (on return filled with actual direction)
3844  * \return 0 otherwise a negative error code if configuration space would become empty
3845  *
3846  * Wanted/actual exact min/max is <,=,> val following dir (-1,0,1)
3847  */
3848 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)
3849 {
3850         unsigned int _min = *min;
3851         unsigned int _max = *max;
3852         int err = snd_pcm_hw_param_set_minmax(pcm, params, SND_TRY, SND_PCM_HW_PARAM_PERIOD_SIZE, &_min, mindir, &_max, maxdir);
3853         *min = _min;
3854         *max = _max;
3855         return err;
3856 }
3857
3858 /**
3859  * \brief Restrict a configuration space to have period size nearest to a target
3860  * \param pcm PCM handle
3861  * \param params Configuration space
3862  * \param val approximate target period size in frames / returned chosen approximate target period size
3863  * \return 0 otherwise a negative error code
3864  *
3865  * target/chosen exact value is <,=,> val following dir (-1,0,1)
3866  *
3867  * Note: To use this function add '#define ALSA_PCM_NEW_HW_PARAMS_API' before '#include <alsa/asoundlib.h>'
3868  *       to enable this new function prototype. Using of older function with same name is deprecated.
3869  */
3870 #ifndef DOXYGEN
3871 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)
3872 #else
3873 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)
3874 #endif
3875 {
3876         unsigned int _val = *val;
3877         int err = snd_pcm_hw_param_set_near(pcm, params, SND_PCM_HW_PARAM_PERIOD_SIZE, &_val, dir);
3878         if (err >= 0)
3879                 *val = _val;
3880         return err;
3881 }
3882
3883 /**
3884  * \brief Restrict a configuration space to contain only its minimum period size
3885  * \param pcm PCM handle
3886  * \param params Configuration space
3887  * \param val Returned maximum approximate period size in frames
3888  * \param dir Sub unit direction
3889  * \return 0 otherwise a negative error code
3890  *
3891  * Actual exact value is <,=,> the approximate one following dir (-1, 0, 1)
3892  *
3893  * Note: To use this function add '#define ALSA_PCM_NEW_HW_PARAMS_API' before '#include <alsa/asoundlib.h>'
3894  *       to enable this new function prototype. Using of older function with same name is deprecated.
3895  */
3896 #ifndef DOXYGEN
3897 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)
3898 #else
3899 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)
3900 #endif
3901 {
3902         unsigned int _val;
3903         int err = snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_PERIOD_SIZE, &_val, dir);
3904         if (err >= 0)
3905                 *val = _val;
3906         return err;
3907 }
3908
3909 /**
3910  * \brief Restrict a configuration space to contain only its maximum period size
3911  * \param pcm PCM handle
3912  * \param params Configuration space
3913  * \param val Returned maximum approximate period size in frames
3914  * \param dir Sub unit direction
3915  * \return 0 otherwise a negative error code
3916  *
3917  * Actual exact value is <,=,> the approximate one following dir (-1, 0, 1)
3918  *
3919  * Note: To use this function add '#define ALSA_PCM_NEW_HW_PARAMS_API' before '#include <alsa/asoundlib.h>'
3920  *       to enable this new function prototype. Using of older function with same name is deprecated.
3921  */
3922 #ifndef DOXYGEN
3923 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)
3924 #else
3925 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)
3926 #endif
3927 {
3928         unsigned int _val;
3929         int err = snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_PERIOD_SIZE, &_val, dir);
3930         if (err >= 0)
3931                 *val = _val;
3932         return err;
3933 }
3934
3935 /**
3936  * \brief Restrict a configuration space to contain only integer period sizes
3937  * \param pcm PCM handle
3938  * \param params Configuration space
3939  * \return 0 otherwise a negative error code if configuration space would become empty
3940  */
3941 int snd_pcm_hw_params_set_period_size_integer(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
3942 {
3943         return snd_pcm_hw_param_set_integer(pcm, params, SND_TRY, SND_PCM_HW_PARAM_PERIOD_SIZE);
3944 }
3945
3946
3947 /**
3948  * \brief Extract periods from a configuration space
3949  * \param params Configuration space
3950  * \param val approximate periods per buffer
3951  * \param dir Sub unit direction
3952  * \return 0 otherwise a negative error code if not exactly one is present
3953  *
3954  * Actual exact value is <,=,> the approximate one following dir (-1, 0, 1)
3955  *
3956  * Note: To use this function add '#define ALSA_PCM_NEW_HW_PARAMS_API' before '#include <alsa/asoundlib.h>'
3957  *       to enable this new function prototype. Using of older function with same name is deprecated.
3958  */
3959 #ifndef DOXYGEN
3960 int INTERNAL(snd_pcm_hw_params_get_periods)(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
3961 #else
3962 int snd_pcm_hw_params_get_periods(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
3963 #endif
3964 {
3965         return snd_pcm_hw_param_get(params, SND_PCM_HW_PARAM_PERIODS, val, dir);
3966 }
3967
3968 /**
3969  * \brief Extract minimum periods count from a configuration space
3970  * \param params Configuration space
3971  * \param val approximate minimum periods per buffer
3972  * \param dir Sub unit direction
3973  * \return 0 otherwise a negative error code
3974  *
3975  * Exact value is <,=,> the returned one following dir (-1,0,1)
3976  *
3977  * Note: To use this function add '#define ALSA_PCM_NEW_HW_PARAMS_API' before '#include <alsa/asoundlib.h>'
3978  *       to enable this new function prototype. Using of older function with same name is deprecated.
3979  */
3980 #ifndef DOXYGEN
3981 int INTERNAL(snd_pcm_hw_params_get_periods_min)(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
3982 #else
3983 int snd_pcm_hw_params_get_periods_min(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
3984 #endif
3985 {
3986         return snd_pcm_hw_param_get_min(params, SND_PCM_HW_PARAM_PERIODS, val, dir);
3987 }
3988
3989 /**
3990  * \brief Extract maximum periods count from a configuration space
3991  * \param params Configuration space
3992  * \param val approximate maximum periods per buffer
3993  * \param dir Sub unit direction
3994  * \return 0 otherwise a negative error code
3995  *
3996  * Exact value is <,=,> the returned one following dir (-1,0,1)
3997  *
3998  * Note: To use this function add '#define ALSA_PCM_NEW_HW_PARAMS_API' before '#include <alsa/asoundlib.h>'
3999  *       to enable this new function prototype. Using of older function with same name is deprecated.
4000  */
4001 #ifndef DOXYGEN
4002 int INTERNAL(snd_pcm_hw_params_get_periods_max)(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4003 #else
4004 int snd_pcm_hw_params_get_periods_max(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4005 #endif
4006 {
4007         return snd_pcm_hw_param_get_max(params, SND_PCM_HW_PARAM_PERIODS, val, dir);
4008 }
4009
4010 /**
4011  * \brief Verify if a periods count is available inside a configuration space for a PCM
4012  * \param pcm PCM handle
4013  * \param params Configuration space
4014  * \param val approximate periods per buffer
4015  * \param dir Sub unit direction
4016  * \return 1 if available 0 otherwise
4017  *
4018  * Wanted exact value is <,=,> val following dir (-1,0,1)
4019  */
4020 int snd_pcm_hw_params_test_periods(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir)
4021 {
4022         return snd_pcm_hw_param_set(pcm, params, SND_TEST, SND_PCM_HW_PARAM_PERIODS, val, dir);
4023 }
4024
4025 /**
4026  * \brief Restrict a configuration space to contain only one periods count
4027  * \param pcm PCM handle
4028  * \param params Configuration space
4029  * \param val approximate periods per buffer
4030  * \param dir Sub unit direction
4031  * \return 0 otherwise a negative error code if configuration space would become empty
4032  *
4033  * Wanted exact value is <,=,> val following dir (-1,0,1)
4034  */
4035 int snd_pcm_hw_params_set_periods(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir)
4036 {
4037         return snd_pcm_hw_param_set(pcm, params, SND_TRY, SND_PCM_HW_PARAM_PERIODS, val, dir);
4038 }
4039
4040 /**
4041  * \brief Restrict a configuration space with a minimum periods count
4042  * \param pcm PCM handle
4043  * \param params Configuration space
4044  * \param val approximate minimum periods per buffer (on return filled with actual minimum)
4045  * \param dir Sub unit direction (on return filled with actual direction)
4046  * \return 0 otherwise a negative error code if configuration space would become empty
4047  *
4048  * Wanted/actual exact minimum is <,=,> val following dir (-1,0,1)
4049  */
4050 int snd_pcm_hw_params_set_periods_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4051 {
4052         return snd_pcm_hw_param_set_min(pcm, params, SND_TRY, SND_PCM_HW_PARAM_PERIODS, val, dir);
4053 }
4054
4055 /**
4056  * \brief Restrict a configuration space with a maximum periods count
4057  * \param pcm PCM handle
4058  * \param params Configuration space
4059  * \param val approximate maximum periods per buffer (on return filled with actual maximum)
4060  * \param dir Sub unit direction (on return filled with actual direction)
4061  * \return 0 otherwise a negative error code if configuration space would become empty
4062  *
4063  * Wanted/actual exact maximum is <,=,> val following dir (-1,0,1)
4064  */
4065 int snd_pcm_hw_params_set_periods_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4066 {
4067         return snd_pcm_hw_param_set_max(pcm, params, SND_TRY, SND_PCM_HW_PARAM_PERIODS, val, dir);
4068 }
4069
4070 /**
4071  * \brief Restrict a configuration space to have periods counts in a given range
4072  * \param pcm PCM handle
4073  * \param params Configuration space
4074  * \param min approximate minimum periods per buffer (on return filled with actual minimum)
4075  * \param mindir Sub unit direction for minimum (on return filled with actual direction)
4076  * \param max approximate maximum periods per buffer (on return filled with actual maximum)
4077  * \param maxdir Sub unit direction for maximum (on return filled with actual direction)
4078  * \return 0 otherwise a negative error code if configuration space would become empty
4079  *
4080  * Wanted/actual exact min/max is <,=,> val following dir (-1,0,1)
4081  */
4082 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)
4083 {
4084         return snd_pcm_hw_param_set_minmax(pcm, params, SND_TRY, SND_PCM_HW_PARAM_PERIODS, min, mindir, max, maxdir);
4085 }
4086
4087 /**
4088  * \brief Restrict a configuration space to have periods count nearest to a target
4089  * \param pcm PCM handle
4090  * \param params Configuration space
4091  * \param val approximate target periods per buffer / returned chosen approximate target periods per buffer
4092  * \return approximate chosen periods per buffer
4093  *
4094  * target/chosen exact value is <,=,> val following dir (-1,0,1)
4095  *
4096  * Note: To use this function add '#define ALSA_PCM_NEW_HW_PARAMS_API' before '#include <alsa/asoundlib.h>'
4097  *       to enable this new function prototype. Using of older function with same name is deprecated.
4098  */
4099 #ifndef DOXYGEN
4100 int INTERNAL(snd_pcm_hw_params_set_periods_near)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4101 #else
4102 int snd_pcm_hw_params_set_periods_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4103 #endif
4104 {
4105         return snd_pcm_hw_param_set_near(pcm, params, SND_PCM_HW_PARAM_PERIODS, val, dir);
4106 }
4107
4108 /**
4109  * \brief Restrict a configuration space to contain only its minimum periods count
4110  * \param pcm PCM handle
4111  * \param params Configuration space
4112  * \param val Returned approximate minimum periods per buffer
4113  * \param dir Sub unit direction
4114  * \return 0 otherwise a negative error code
4115  *
4116  * Actual exact value is <,=,> the approximate one following dir (-1, 0, 1)
4117  *
4118  * Note: To use this function add '#define ALSA_PCM_NEW_HW_PARAMS_API' before '#include <alsa/asoundlib.h>'
4119  *       to enable this new function prototype. Using of older function with same name is deprecated.
4120  */
4121 #ifndef DOXYGEN
4122 int INTERNAL(snd_pcm_hw_params_set_periods_first)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4123 #else
4124 int snd_pcm_hw_params_set_periods_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4125 #endif
4126 {
4127         return snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_PERIODS, val, dir);
4128 }
4129
4130 /**
4131  * \brief Restrict a configuration space to contain only its maximum periods count
4132  * \param pcm PCM handle
4133  * \param params Configuration space
4134  * \param val Returned approximate maximum periods per buffer
4135  * \param dir Sub unit direction
4136  * \return 0 otherwise a negative error code
4137  *
4138  * Actual exact value is <,=,> the approximate one following dir (-1, 0, 1)
4139  *
4140  * Note: To use this function add '#define ALSA_PCM_NEW_HW_PARAMS_API' before '#include <alsa/asoundlib.h>'
4141  *       to enable this new function prototype. Using of older function with same name is deprecated.
4142  */
4143 #ifndef DOXYGEN
4144 int INTERNAL(snd_pcm_hw_params_set_periods_last)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4145 #else
4146 int snd_pcm_hw_params_set_periods_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4147 #endif
4148 {
4149         return snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_PERIODS, val, dir);
4150 }
4151
4152 /**
4153  * \brief Restrict a configuration space to contain only integer periods counts
4154  * \param pcm PCM handle
4155  * \param params Configuration space
4156  * \return 0 otherwise a negative error code if configuration space would become empty
4157  */
4158 int snd_pcm_hw_params_set_periods_integer(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
4159 {
4160         return snd_pcm_hw_param_set_integer(pcm, params, SND_TRY, SND_PCM_HW_PARAM_PERIODS);
4161 }
4162
4163
4164 /**
4165  * \brief Extract buffer time from a configuration space
4166  * \param params Configuration space
4167  * \param approximate buffer duration in us
4168  * \param val Returned buffer time in us
4169  * \param dir Sub unit direction
4170  * \return 0 otherwise a negative error code if not exactly one is present
4171  *
4172  * Actual exact value is <,=,> the approximate one following dir (-1, 0, 1)
4173  *
4174  * Note: To use this function add '#define ALSA_PCM_NEW_HW_PARAMS_API' before '#include <alsa/asoundlib.h>'
4175  *       to enable this new function prototype. Using of older function with same name is deprecated.
4176  */
4177 #ifndef DOXYGEN
4178 int INTERNAL(snd_pcm_hw_params_get_buffer_time)(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4179 #else
4180 int snd_pcm_hw_params_get_buffer_time(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4181 #endif
4182 {
4183         return snd_pcm_hw_param_get(params, SND_PCM_HW_PARAM_BUFFER_TIME, val, dir);
4184 }
4185
4186 /**
4187  * \brief Extract minimum buffer time from a configuration space
4188  * \param params Configuration space
4189  * \param val approximate minimum buffer duration in us
4190  * \param dir Sub unit direction
4191  * \return 0 otherwise a negative error code
4192  *
4193  * Exact value is <,=,> the returned one following dir (-1,0,1)
4194  *
4195  * Note: To use this function add '#define ALSA_PCM_NEW_HW_PARAMS_API' before '#include <alsa/asoundlib.h>'
4196  *       to enable this new function prototype. Using of older function with same name is deprecated.
4197  */
4198 #ifndef DOXYGEN
4199 int INTERNAL(snd_pcm_hw_params_get_buffer_time_min)(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4200 #else
4201 int snd_pcm_hw_params_get_buffer_time_min(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4202 #endif
4203 {
4204         return snd_pcm_hw_param_get_min(params, SND_PCM_HW_PARAM_BUFFER_TIME, val, dir);
4205 }
4206
4207 /**
4208  * \brief Extract maximum buffer time from a configuration space
4209  * \param params Configuration space
4210  * \param val approximate maximum buffer duration in us
4211  * \param dir Sub unit direction
4212  * \return 0 otherwise a negative error code
4213  *
4214  * Exact value is <,=,> the returned one following dir (-1,0,1)
4215  *
4216  * Note: To use this function add '#define ALSA_PCM_NEW_HW_PARAMS_API' before '#include <alsa/asoundlib.h>'
4217  *       to enable this new function prototype. Using of older function with same name is deprecated.
4218  */
4219 #ifndef DOXYGEN
4220 int INTERNAL(snd_pcm_hw_params_get_buffer_time_max)(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4221 #else
4222 int snd_pcm_hw_params_get_buffer_time_max(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4223 #endif
4224 {
4225         return snd_pcm_hw_param_get_max(params, SND_PCM_HW_PARAM_BUFFER_TIME, val, dir);
4226 }
4227
4228 /**
4229  * \brief Verify if a buffer time is available inside a configuration space for a PCM
4230  * \param pcm PCM handle
4231  * \param params Configuration space
4232  * \param val approximate buffer duration in us
4233  * \param dir Sub unit direction
4234  * \return 1 if available 0 otherwise
4235  *
4236  * Wanted exact value is <,=,> val following dir (-1,0,1)
4237  */
4238 int snd_pcm_hw_params_test_buffer_time(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir)
4239 {
4240         return snd_pcm_hw_param_set(pcm, params, SND_TEST, SND_PCM_HW_PARAM_BUFFER_TIME, val, dir);
4241 }
4242
4243 /**
4244  * \brief Restrict a configuration space to contain only one buffer time
4245  * \param pcm PCM handle
4246  * \param params Configuration space
4247  * \param val approximate buffer duration in us
4248  * \param dir Sub unit direction
4249  * \return 0 otherwise a negative error code if configuration space would become empty
4250  *
4251  * Wanted exact value is <,=,> val following dir (-1,0,1)
4252  */
4253 int snd_pcm_hw_params_set_buffer_time(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir)
4254 {
4255         return snd_pcm_hw_param_set(pcm, params, SND_TRY, SND_PCM_HW_PARAM_BUFFER_TIME, val, dir);
4256 }
4257
4258 /**
4259  * \brief Restrict a configuration space with a minimum buffer time
4260  * \param pcm PCM handle
4261  * \param params Configuration space
4262  * \param val approximate minimum buffer duration in us (on return filled with actual minimum)
4263  * \param dir Sub unit direction (on return filled with actual direction)
4264  * \return 0 otherwise a negative error code if configuration space would become empty
4265  *
4266  * Wanted/actual exact minimum is <,=,> val following dir (-1,0,1)
4267  */
4268 int snd_pcm_hw_params_set_buffer_time_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4269 {
4270         return snd_pcm_hw_param_set_min(pcm, params, SND_TRY, SND_PCM_HW_PARAM_BUFFER_TIME, val, dir);
4271 }
4272
4273 /**
4274  * \brief Restrict a configuration space with a maximum buffer time
4275  * \param pcm PCM handle
4276  * \param params Configuration space
4277  * \param val approximate maximum buffer duration in us (on return filled with actual maximum)
4278  * \param dir Sub unit direction (on return filled with actual direction)
4279  * \return 0 otherwise a negative error code if configuration space would become empty
4280  *
4281  * Wanted/actual exact maximum is <,=,> val following dir (-1,0,1)
4282  */
4283 int snd_pcm_hw_params_set_buffer_time_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4284 {
4285         return snd_pcm_hw_param_set_max(pcm, params, SND_TRY, SND_PCM_HW_PARAM_BUFFER_TIME, val, dir);
4286 }
4287
4288 /**
4289  * \brief Restrict a configuration space to have buffer times in a given range
4290  * \param pcm PCM handle
4291  * \param params Configuration space
4292  * \param min approximate minimum buffer duration in us (on return filled with actual minimum)
4293  * \param mindir Sub unit direction for minimum (on return filled with actual direction)
4294  * \param max approximate maximum buffer duration in us (on return filled with actual maximum)
4295  * \param maxdir Sub unit direction for maximum (on return filled with actual direction)
4296  * \return 0 otherwise a negative error code if configuration space would become empty
4297  *
4298  * Wanted/actual exact min/max is <,=,> val following dir (-1,0,1)
4299  */
4300 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)
4301 {
4302         return snd_pcm_hw_param_set_minmax(pcm, params, SND_TRY, SND_PCM_HW_PARAM_BUFFER_TIME, min, mindir, max, maxdir);
4303 }
4304
4305 /**
4306  * \brief Restrict a configuration space to have buffer time nearest to a target
4307  * \param pcm PCM handle
4308  * \param params Configuration space
4309  * \param val approximate target buffer duration in us / returned chosen approximate target buffer duration
4310  * \return approximate chosen buffer duration in us
4311  *
4312  * target/chosen exact value is <,=,> val following dir (-1,0,1)
4313  *
4314  * Note: To use this function add '#define ALSA_PCM_NEW_HW_PARAMS_API' before '#include <alsa/asoundlib.h>'
4315  *       to enable this new function prototype. Using of older function with same name is deprecated.
4316  */
4317 #ifndef DOXYGEN
4318 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)
4319 #else
4320 int snd_pcm_hw_params_set_buffer_time_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4321 #endif
4322 {
4323         return snd_pcm_hw_param_set_near(pcm, params, SND_PCM_HW_PARAM_BUFFER_TIME, val, dir);
4324 }
4325
4326 /**
4327  * \brief Restrict a configuration space to contain only its minimum buffer time
4328  * \param pcm PCM handle
4329  * \param params Configuration space
4330  * \param val Returned approximate minimum buffer duration in us
4331  * \param dir Sub unit direction
4332  * \return 0 otherwise a negative error code
4333  *
4334  * Actual exact value is <,=,> the approximate one following dir (-1, 0, 1)
4335  *
4336  * Note: To use this function add '#define ALSA_PCM_NEW_HW_PARAMS_API' before '#include <alsa/asoundlib.h>'
4337  *       to enable this new function prototype. Using of older function with same name is deprecated.
4338  */
4339 #ifndef DOXYGEN
4340 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)
4341 #else
4342 int snd_pcm_hw_params_set_buffer_time_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4343 #endif
4344 {
4345         return snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_BUFFER_TIME, val, dir);
4346 }
4347
4348 /**
4349  * \brief Restrict a configuration space to contain only its maximum buffered time
4350  * \param pcm PCM handle
4351  * \param params Configuration space
4352  * \param val Returned approximate maximum buffer duration in us
4353  * \param dir Sub unit direction
4354  * \return 0 otherwise a negative error code
4355  *
4356  * Actual exact value is <,=,> the approximate one following dir (-1, 0, 1)
4357  *
4358  * Note: To use this function add '#define ALSA_PCM_NEW_HW_PARAMS_API' before '#include <alsa/asoundlib.h>'
4359  *       to enable this new function prototype. Using of older function with same name is deprecated.
4360  */
4361 #ifndef DOXYGEN
4362 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)
4363 #else
4364 int snd_pcm_hw_params_set_buffer_time_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4365 #endif
4366 {
4367         return snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_BUFFER_TIME, val, dir);
4368 }
4369
4370
4371 /**
4372  * \brief Extract buffer size from a configuration space
4373  * \param params Configuration space
4374  * \param val Returned buffer size in frames
4375  * \return 0 otherwise a negative error code if not exactly one is present
4376  *
4377  * Note: To use this function add '#define ALSA_PCM_NEW_HW_PARAMS_API' before '#include <alsa/asoundlib.h>'
4378  *       to enable this new function prototype. Using of older function with same name is deprecated.
4379  */
4380 #ifndef DOXYGEN
4381 int INTERNAL(snd_pcm_hw_params_get_buffer_size)(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val)
4382 #else
4383 int snd_pcm_hw_params_get_buffer_size(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val)
4384 #endif
4385 {
4386         unsigned int _val;
4387         int err = snd_pcm_hw_param_get(params, SND_PCM_HW_PARAM_BUFFER_SIZE, &_val, NULL);
4388         if (err >= 0)
4389                 *val = _val;
4390         return err;
4391 }
4392
4393 /**
4394  * \brief Extract minimum buffer size from a configuration space
4395  * \param params Configuration space
4396  * \param val Returned approximate minimum buffer size in frames
4397  * \param dir Sub unit direction
4398  * \return 0 otherwise a negative error code
4399  *
4400  * Exact value is <,=,> the returned one following dir (-1,0,1)
4401  *
4402  * Note: To use this function add '#define ALSA_PCM_NEW_HW_PARAMS_API' before '#include <alsa/asoundlib.h>'
4403  *       to enable this new function prototype. Using of older function with same name is deprecated.
4404  */
4405 #ifndef DOXYGEN
4406 int INTERNAL(snd_pcm_hw_params_get_buffer_size_min)(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val)
4407 #else
4408 int snd_pcm_hw_params_get_buffer_size_min(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val)
4409 #endif
4410 {
4411         unsigned int _val;
4412         int err = snd_pcm_hw_param_get_min(params, SND_PCM_HW_PARAM_BUFFER_SIZE, &_val, NULL);
4413         if (err >= 0)
4414                 *val = _val;
4415         return err;
4416 }
4417
4418 /**
4419  * \brief Extract maximum buffer size from a configuration space
4420  * \param params Configuration space
4421  * \param val Returned approximate maximum buffer size in frames
4422  * \param dir Sub unit direction
4423  * \return 0 otherwise a negative error code
4424  *
4425  * Exact value is <,=,> the returned one following dir (-1,0,1)
4426  *
4427  * Note: To use this function add '#define ALSA_PCM_NEW_HW_PARAMS_API' before '#include <alsa/asoundlib.h>'
4428  *       to enable this new function prototype. Using of older function with same name is deprecated.
4429  */
4430 #ifndef DOXYGEN
4431 int INTERNAL(snd_pcm_hw_params_get_buffer_size_max)(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val)
4432 #else
4433 int snd_pcm_hw_params_get_buffer_size_max(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val)
4434 #endif
4435 {
4436         unsigned int _val;
4437         int err = snd_pcm_hw_param_get_max(params, SND_PCM_HW_PARAM_BUFFER_SIZE, &_val, NULL);
4438         if (err >= 0)
4439                 *val = _val;
4440         return err;
4441 }
4442
4443 /**
4444  * \brief Verify if a buffer size is available inside a configuration space for a PCM
4445  * \param pcm PCM handle
4446  * \param params Configuration space
4447  * \param val buffer size in frames
4448  * \param dir Sub unit direction
4449  * \return 1 if available 0 otherwise
4450  *
4451  * Wanted exact value is <,=,> val following dir (-1,0,1)
4452  */
4453 int snd_pcm_hw_params_test_buffer_size(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val)
4454 {
4455         return snd_pcm_hw_param_set(pcm, params, SND_TEST, SND_PCM_HW_PARAM_BUFFER_SIZE, val, 0);
4456 }
4457
4458 /**
4459  * \brief Restrict a configuration space to contain only one buffer size
4460  * \param pcm PCM handle
4461  * \param params Configuration space
4462  * \param val buffer size in frames
4463  * \return 0 otherwise a negative error code if configuration space would become empty
4464  *
4465  * Wanted exact value is <,=,> val following dir (-1,0,1)
4466  */
4467 int snd_pcm_hw_params_set_buffer_size(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val)
4468 {
4469         return snd_pcm_hw_param_set(pcm, params, SND_TRY, SND_PCM_HW_PARAM_BUFFER_SIZE, val, 0);
4470 }
4471
4472 /**
4473  * \brief Restrict a configuration space with a minimum buffer size
4474  * \param pcm PCM handle
4475  * \param params Configuration space
4476  * \param val approximate minimum buffer size in frames (on return filled with actual minimum)
4477  * \param dir Sub unit direction (on return filled with actual direction)
4478  * \return 0 otherwise a negative error code if configuration space would become empty
4479  *
4480  * Wanted/actual exact minimum is <,=,> val following dir (-1,0,1)
4481  */
4482 int snd_pcm_hw_params_set_buffer_size_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val)
4483 {
4484         unsigned int _val = *val;
4485         int err = snd_pcm_hw_param_set_min(pcm, params, SND_TRY, SND_PCM_HW_PARAM_BUFFER_SIZE, &_val, NULL);
4486         if (err >= 0)
4487                 *val = _val;
4488         return err;
4489 }
4490
4491 /**
4492  * \brief Restrict a configuration space with a maximum buffer size
4493  * \param pcm PCM handle
4494  * \param params Configuration space
4495  * \param val approximate maximum buffer size in frames (on return filled with actual maximum)
4496  * \param dir Sub unit direction (on return filled with actual direction)
4497  * \return 0 otherwise a negative error code if configuration space would become empty
4498  *
4499  * Wanted/actual exact minimum is <,=,> val following dir (-1,0,1)
4500  */
4501 int snd_pcm_hw_params_set_buffer_size_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val)
4502 {
4503         unsigned int _val = *val;
4504         int err = snd_pcm_hw_param_set_max(pcm, params, SND_TRY, SND_PCM_HW_PARAM_BUFFER_SIZE, &_val, NULL);
4505         if (err >= 0)
4506                 *val = _val;
4507         return err;
4508 }
4509
4510 /**
4511  * \brief Restrict a configuration space to have buffer sizes in a given range
4512  * \param pcm PCM handle
4513  * \param params Configuration space
4514  * \param min approximate minimum buffer size in frames (on return filled with actual minimum)
4515  * \param mindir Sub unit direction for minimum (on return filled with actual direction)
4516  * \param max approximate maximum buffer size in frames (on return filled with actual maximum)
4517  * \param maxdir Sub unit direction for maximum (on return filled with actual direction)
4518  * \return 0 otherwise a negative error code if configuration space would become empty
4519  *
4520  * Wanted/actual exact min/max is <,=,> val following dir (-1,0,1)
4521  */
4522 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)
4523 {
4524         unsigned int _min = *min;
4525         unsigned int _max = *max;
4526         int err = snd_pcm_hw_param_set_minmax(pcm, params, SND_TRY, SND_PCM_HW_PARAM_BUFFER_SIZE, &_min, NULL, &_max, NULL);
4527         *min = _min;
4528         *max = _max;
4529         return err;
4530 }
4531
4532 /**
4533  * \brief Restrict a configuration space to have buffer size nearest to a target
4534  * \param pcm PCM handle
4535  * \param params Configuration space
4536  * \param val approximate target buffer size in frames / returned chosen approximate target buffer size in frames
4537  * \return approximate chosen buffer size in frames
4538  *
4539  * target/chosen exact value is <,=,> val following dir (-1,0,1)
4540  *
4541  * Note: To use this function add '#define ALSA_PCM_NEW_HW_PARAMS_API' before '#include <alsa/asoundlib.h>'
4542  *       to enable this new function prototype. Using of older function with same name is deprecated.
4543  */
4544 #ifndef DOXYGEN
4545 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)
4546 #else
4547 int snd_pcm_hw_params_set_buffer_size_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val)
4548 #endif
4549 {
4550         unsigned int _val = *val;
4551         int err = snd_pcm_hw_param_set_near(pcm, params, SND_PCM_HW_PARAM_BUFFER_SIZE, &_val, NULL);
4552         if (err >= 0)
4553                 *val = _val;
4554         return err;
4555 }
4556
4557 /**
4558  * \brief Restrict a configuration space to contain only its minimum buffer size
4559  * \param pcm PCM handle
4560  * \param params Configuration space
4561  * \param val Returned minimum buffer size in frames
4562  * \return buffer size in frames
4563  *
4564  * Note: To use this function add '#define ALSA_PCM_NEW_HW_PARAMS_API' before '#include <alsa/asoundlib.h>'
4565  *       to enable this new function prototype. Using of older function with same name is deprecated.
4566  */
4567 #ifndef DOXYGEN
4568 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)
4569 #else
4570 int snd_pcm_hw_params_set_buffer_size_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val)
4571 #endif
4572 {
4573         unsigned int _val;
4574         int err = snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_BUFFER_SIZE, &_val, NULL);
4575         if (err >= 0)
4576                 *val = _val;
4577         return err;
4578 }
4579
4580 /**
4581  * \brief Restrict a configuration space to contain only its maximum buffer size
4582  * \param pcm PCM handle
4583  * \param params Configuration space
4584  * \param val Returned maximum buffer size in frames
4585  * \return 0 otherwise a negative error code
4586  *
4587  * Note: To use this function add '#define ALSA_PCM_NEW_HW_PARAMS_API' before '#include <alsa/asoundlib.h>'
4588  *       to enable this new function prototype. Using of older function with same name is deprecated.
4589  */
4590 #ifndef DOXYGEN
4591 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)
4592 #else
4593 int snd_pcm_hw_params_set_buffer_size_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val)
4594 #endif
4595 {
4596         unsigned int _val;
4597         int err = snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_BUFFER_SIZE, &_val, NULL);
4598         if (err >= 0)
4599                 *val = _val;
4600         return err;
4601 }
4602
4603
4604 /**
4605  * \brief Extract tick time from a configuration space
4606  * \param params Configuration space
4607  * \param val Returned approximate tick duration in us
4608  * \param dir Sub unit direction
4609  * \return 0 otherwise a negative error code if not exactly one is present
4610  *
4611  * Actual exact value is <,=,> the approximate one following dir (-1, 0, 1)
4612  *
4613  * Note: To use this function add '#define ALSA_PCM_NEW_HW_PARAMS_API' before '#include <alsa/asoundlib.h>'
4614  *       to enable this new function prototype. Using of older function with same name is deprecated.
4615  */
4616 #ifndef DOXYGEN
4617 int INTERNAL(snd_pcm_hw_params_get_tick_time)(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4618 #else
4619 int snd_pcm_hw_params_get_tick_time(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4620 #endif
4621 {
4622         return snd_pcm_hw_param_get(params, SND_PCM_HW_PARAM_TICK_TIME, val, dir);
4623 }
4624
4625 /**
4626  * \brief Extract minimum tick time from a configuration space
4627  * \param params Configuration space
4628  * \param val Returned approximate minimum tick duration in us
4629  * \param dir Sub unit direction
4630  * \return 0 otherwise a negative error code
4631  *
4632  * Exact value is <,=,> the returned one following dir (-1,0,1)
4633  *
4634  * Note: To use this function add '#define ALSA_PCM_NEW_HW_PARAMS_API' before '#include <alsa/asoundlib.h>'
4635  *       to enable this new function prototype. Using of older function with same name is deprecated.
4636  */
4637 #ifndef DOXYGEN
4638 int INTERNAL(snd_pcm_hw_params_get_tick_time_min)(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4639 #else
4640 int snd_pcm_hw_params_get_tick_time_min(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4641 #endif
4642 {
4643         return snd_pcm_hw_param_get_min(params, SND_PCM_HW_PARAM_TICK_TIME, val, dir);
4644 }
4645
4646 /**
4647  * \brief Extract maximum tick time from a configuration space
4648  * \param params Configuration space
4649  * \param val Returned approximate maximum tick duration in us
4650  * \param dir Sub unit direction
4651  * \return 0 otherwise a negative error code
4652  *
4653  * Exact value is <,=,> the returned one following dir (-1,0,1)
4654  *
4655  * Note: To use this function add '#define ALSA_PCM_NEW_HW_PARAMS_API' before '#include <alsa/asoundlib.h>'
4656  *       to enable this new function prototype. Using of older function with same name is deprecated.
4657  */
4658 #ifndef DOXYGEN
4659 int INTERNAL(snd_pcm_hw_params_get_tick_time_max)(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4660 #else
4661 int snd_pcm_hw_params_get_tick_time_max(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4662 #endif
4663 {
4664         return snd_pcm_hw_param_get_max(params, SND_PCM_HW_PARAM_TICK_TIME, val, dir);
4665 }
4666
4667 /**
4668  * \brief Verify if a tick time is available inside a configuration space for a PCM
4669  * \param pcm PCM handle
4670  * \param params Configuration space
4671  * \param val approximate tick duration in us
4672  * \param dir Sub unit direction
4673  * \return 1 if available 0 otherwise
4674  *
4675  * Wanted exact value is <,=,> val following dir (-1,0,1)
4676  */
4677 int snd_pcm_hw_params_test_tick_time(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir)
4678 {
4679         return snd_pcm_hw_param_set(pcm, params, SND_TEST, SND_PCM_HW_PARAM_TICK_TIME, val, dir);
4680 }
4681
4682 /**
4683  * \brief Restrict a configuration space to contain only one tick time
4684  * \param pcm PCM handle
4685  * \param params Configuration space
4686  * \param val approximate tick duration in us
4687  * \param dir Sub unit direction
4688  * \return 0 otherwise a negative error code if configuration space would become empty
4689  *
4690  * Wanted exact value is <,=,> val following dir (-1,0,1)
4691  */
4692 int snd_pcm_hw_params_set_tick_time(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir)
4693 {
4694         return snd_pcm_hw_param_set(pcm, params, SND_TRY, SND_PCM_HW_PARAM_TICK_TIME, val, dir);
4695 }
4696
4697 /**
4698  * \brief Restrict a configuration space with a minimum tick time
4699  * \param pcm PCM handle
4700  * \param params Configuration space
4701  * \param val approximate minimum tick duration in us (on return filled with actual minimum)
4702  * \param dir Sub unit direction (on return filled with actual direction)
4703  * \return 0 otherwise a negative error code if configuration space would become empty
4704  *
4705  * Wanted/actual exact minimum is <,=,> val following dir (-1,0,1)
4706  */
4707 int snd_pcm_hw_params_set_tick_time_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4708 {
4709         return snd_pcm_hw_param_set_min(pcm, params, SND_TRY, SND_PCM_HW_PARAM_TICK_TIME, val, dir);
4710 }
4711
4712 /**
4713  * \brief Restrict a configuration space with a maximum tick time
4714  * \param pcm PCM handle
4715  * \param params Configuration space
4716  * \param val approximate maximum tick duration in us (on return filled with actual maximum)
4717  * \param dir Sub unit direction (on return filled with actual direction)
4718  * \return 0 otherwise a negative error code if configuration space would become empty
4719  *
4720  * Wanted/actual exact maximum is <,=,> val following dir (-1,0,1)
4721  */
4722 int snd_pcm_hw_params_set_tick_time_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4723 {
4724         return snd_pcm_hw_param_set_max(pcm, params, SND_TRY, SND_PCM_HW_PARAM_TICK_TIME, val, dir);
4725 }
4726
4727 /**
4728  * \brief Restrict a configuration space to have tick times in a given range
4729  * \param pcm PCM handle
4730  * \param params Configuration space
4731  * \param min approximate minimum tick duration in us (on return filled with actual minimum)
4732  * \param mindir Sub unit direction for minimum (on return filled with actual direction)
4733  * \param max approximate maximum tick duration in us (on return filled with actual maximum)
4734  * \param maxdir Sub unit direction for maximum (on return filled with actual direction)
4735  * \return 0 otherwise a negative error code if configuration space would become empty
4736  *
4737  * Wanted/actual exact min/max is <,=,> val following dir (-1,0,1)
4738  */
4739 int snd_pcm_hw_params_set_tick_time_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *min, int *mindir, unsigned int *max, int *maxdir)
4740 {
4741         return snd_pcm_hw_param_set_minmax(pcm, params, SND_TRY, SND_PCM_HW_PARAM_TICK_TIME, min, mindir, max, maxdir);
4742 }
4743
4744 /**
4745  * \brief Restrict a configuration space to have tick time nearest to a target
4746  * \param pcm PCM handle
4747  * \param params Configuration space
4748  * \param val approximate target tick duration in us / returned chosen approximate target tick duration in us
4749  * \return approximate chosen tick duration in us
4750  *
4751  * target/chosen exact value is <,=,> val following dir (-1,0,1)
4752  *
4753  * Note: To use this function add '#define ALSA_PCM_NEW_HW_PARAMS_API' before '#include <alsa/asoundlib.h>'
4754  *       to enable this new function prototype. Using of older function with same name is deprecated.
4755  */
4756 #ifndef DOXYGEN
4757 int INTERNAL(snd_pcm_hw_params_set_tick_time_near)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4758 #else
4759 int snd_pcm_hw_params_set_tick_time_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4760 #endif
4761 {
4762         return snd_pcm_hw_param_set_near(pcm, params, SND_PCM_HW_PARAM_TICK_TIME, val, dir);
4763 }
4764
4765 /**
4766  * \brief Restrict a configuration space to contain only its minimum tick time
4767  * \param pcm PCM handle
4768  * \param params Configuration space
4769  * \param val Returned approximate minimum tick duration in us
4770  * \param dir Sub unit direction
4771  * \return 0 otherwise a negative error code
4772  *
4773  * Actual exact value is <,=,> the approximate one following dir (-1, 0, 1)
4774  *
4775  * Note: To use this function add '#define ALSA_PCM_NEW_HW_PARAMS_API' before '#include <alsa/asoundlib.h>'
4776  *       to enable this new function prototype. Using of older function with same name is deprecated.
4777  */
4778 #ifndef DOXYGEN
4779 int INTERNAL(snd_pcm_hw_params_set_tick_time_first)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4780 #else
4781 int snd_pcm_hw_params_set_tick_time_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4782 #endif
4783 {
4784         return snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_TICK_TIME, val, dir);
4785 }
4786
4787 /**
4788  * \brief Restrict a configuration space to contain only its maximum tick time
4789  * \param pcm PCM handle
4790  * \param params Configuration space
4791  * \param val Returned approximate maximum tick duration in us
4792  * \param dir Sub unit direction
4793  * \return 0 otherwise a negative error code
4794  *
4795  * Actual exact value is <,=,> the approximate one following dir (-1, 0, 1)
4796  *
4797  * Note: To use this function add '#define ALSA_PCM_NEW_HW_PARAMS_API' before '#include <alsa/asoundlib.h>'
4798  *       to enable this new function prototype. Using of older function with same name is deprecated.
4799  */
4800 #ifndef DOXYGEN
4801 int INTERNAL(snd_pcm_hw_params_set_tick_time_last)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4802 #else
4803 int snd_pcm_hw_params_set_tick_time_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4804 #endif
4805 {
4806         return snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_TICK_TIME, val, dir);
4807 }
4808
4809 /**
4810  * \brief Get the minimum transfer align value in samples
4811  * \param params Configuration space
4812  * \param val Returned minimum align value
4813  * \return 0 otherwise a negative error code if not exactly one is present
4814  */
4815 int snd_pcm_hw_params_get_min_align(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val)
4816 {
4817         unsigned int format, channels, fb, min_align;
4818         int err;
4819
4820         err = snd_pcm_hw_param_get(params, SND_PCM_HW_PARAM_FORMAT, &format, NULL);
4821         if (err < 0)
4822                 return err;
4823         err = snd_pcm_hw_param_get(params, SND_PCM_HW_PARAM_CHANNELS, &channels, NULL);
4824         if (err < 0)
4825                 return err;
4826         // compute frame bits
4827         fb = snd_pcm_format_physical_width((snd_pcm_format_t)format) * channels;
4828         min_align = 1;
4829         while (fb % 8) {
4830                 fb *= 2;
4831                 min_align *= 2;
4832         }
4833         if (val)
4834                 *val = min_align;
4835         return 0;
4836 }
4837
4838 /**
4839  * \brief Return current software configuration for a PCM
4840  * \param pcm PCM handle
4841  * \param params Software configuration container
4842  * \return 0 on success otherwise a negative error code
4843  */
4844 int snd_pcm_sw_params_current(snd_pcm_t *pcm, snd_pcm_sw_params_t *params)
4845 {
4846         assert(pcm && params);
4847         assert(pcm->setup);
4848         params->tstamp_mode = pcm->tstamp_mode;
4849         params->period_step = pcm->period_step;
4850         params->sleep_min = pcm->sleep_min;
4851         params->avail_min = pcm->avail_min;
4852         params->xfer_align = pcm->xfer_align;
4853         params->start_threshold = pcm->start_threshold;
4854         params->stop_threshold = pcm->stop_threshold;
4855         params->silence_threshold = pcm->silence_threshold;
4856         params->silence_size = pcm->silence_size;
4857         params->boundary = pcm->boundary;
4858         return 0;
4859 }
4860
4861 /**
4862  * \brief Dump a software configuration
4863  * \param params Software configuration container
4864  * \param out Output handle
4865  * \return 0 on success otherwise a negative error code
4866  */
4867 int snd_pcm_sw_params_dump(snd_pcm_sw_params_t *params, snd_output_t *out)
4868 {
4869         snd_output_printf(out, "start_mode: %s\n", snd_pcm_start_mode_name(snd_pcm_sw_params_get_start_mode(params)));
4870         snd_output_printf(out, "xrun_mode: %s\n", snd_pcm_xrun_mode_name(snd_pcm_sw_params_get_xrun_mode(params)));
4871         snd_output_printf(out, "tstamp_mode: %s\n", snd_pcm_tstamp_mode_name(snd_pcm_sw_params_get_tstamp_mode(params)));
4872         snd_output_printf(out, "period_step: %u\n", params->period_step);
4873         snd_output_printf(out, "sleep_min: %u\n", params->sleep_min);
4874         snd_output_printf(out, "avail_min: %lu\n", params->avail_min);
4875         snd_output_printf(out, "xfer_align: %lu\n", params->xfer_align);
4876         snd_output_printf(out, "silence_threshold: %lu\n", params->silence_threshold);
4877         snd_output_printf(out, "silence_size: %lu\n", params->silence_size);
4878         snd_output_printf(out, "boundary: %lu\n", params->boundary);
4879         return 0;
4880 }
4881
4882 /**
4883  * \brief get size of #snd_pcm_sw_params_t
4884  * \return size in bytes
4885  */
4886 size_t snd_pcm_sw_params_sizeof()
4887 {
4888         return sizeof(snd_pcm_sw_params_t);
4889 }
4890
4891 /**
4892  * \brief allocate an invalid #snd_pcm_sw_params_t using standard malloc
4893  * \param ptr returned pointer
4894  * \return 0 on success otherwise negative error code
4895  */
4896 int snd_pcm_sw_params_malloc(snd_pcm_sw_params_t **ptr)
4897 {
4898         assert(ptr);
4899         *ptr = calloc(1, sizeof(snd_pcm_sw_params_t));
4900         if (!*ptr)
4901                 return -ENOMEM;
4902         return 0;
4903 }
4904
4905 /**
4906  * \brief frees a previously allocated #snd_pcm_sw_params_t
4907  * \param pointer to object to free
4908  */
4909 void snd_pcm_sw_params_free(snd_pcm_sw_params_t *obj)
4910 {
4911         free(obj);
4912 }
4913
4914 /**
4915  * \brief copy one #snd_pcm_sw_params_t to another
4916  * \param dst pointer to destination
4917  * \param src pointer to source
4918  */
4919 void snd_pcm_sw_params_copy(snd_pcm_sw_params_t *dst, const snd_pcm_sw_params_t *src)
4920 {
4921         assert(dst && src);
4922         *dst = *src;
4923 }
4924
4925 /**
4926  * \brief (DEPRECATED) Set start mode inside a software configuration container
4927  * \param pcm PCM handle
4928  * \param params Software configuration container
4929  * \param val Start mode
4930  * \return 0 otherwise a negative error code
4931  */
4932 int snd_pcm_sw_params_set_start_mode(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_start_t val)
4933 {
4934         assert(pcm && params);
4935         switch (val) {
4936         case SND_PCM_START_DATA:
4937                 params->start_threshold = 1;
4938                 break;
4939         case SND_PCM_START_EXPLICIT:
4940                 params->start_threshold = pcm->boundary;
4941                 break;
4942         default:
4943                 assert(0);
4944                 break;
4945         }
4946         return 0;
4947 }
4948
4949 #ifndef DOC_HIDDEN
4950 link_warning(snd_pcm_sw_params_set_start_mode, "Warning: start_mode is deprecated, consider to use start_threshold");
4951 #endif
4952
4953 /**
4954  * \brief (DEPRECATED) Get start mode from a software configuration container
4955  * \param params Software configuration container
4956  * \return start mode
4957  */
4958 snd_pcm_start_t snd_pcm_sw_params_get_start_mode(const snd_pcm_sw_params_t *params)
4959 {
4960         assert(params);
4961         /* FIXME: Ugly */
4962         return params->start_threshold > 1024 * 1024 ? SND_PCM_START_EXPLICIT : SND_PCM_START_DATA;
4963 }
4964
4965 #ifndef DOC_HIDDEN
4966 link_warning(snd_pcm_sw_params_get_start_mode, "Warning: start_mode is deprecated, consider to use start_threshold");
4967 #endif
4968
4969 /**
4970  * \brief (DEPRECATED) Set xrun mode inside a software configuration container
4971  * \param pcm PCM handle
4972  * \param params Software configuration container
4973  * \param val Xrun mode
4974  * \return 0 otherwise a negative error code
4975  */
4976 #ifndef DOXYGEN
4977 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)
4978 #else
4979 int snd_pcm_sw_params_set_xrun_mode(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_xrun_t val)
4980 #endif
4981 {
4982         assert(pcm && params);
4983         switch (val) {
4984         case SND_PCM_XRUN_STOP:
4985                 params->stop_threshold = pcm->buffer_size;
4986                 break;
4987         case SND_PCM_XRUN_NONE:
4988                 params->stop_threshold = pcm->boundary;
4989                 break;
4990         default:
4991                 assert(0);
4992                 break;
4993         }
4994         return 0;
4995 }
4996
4997 #ifndef DOC_HIDDEN
4998 link_warning(snd_pcm_sw_params_set_xrun_mode, "Warning: xrun_mode is deprecated, consider to use stop_threshold");
4999 #endif
5000
5001 /**
5002  * \brief (DEPRECATED) Get xrun mode from a software configuration container
5003  * \param params Software configuration container
5004  * \return xrun mode
5005  */
5006 snd_pcm_xrun_t snd_pcm_sw_params_get_xrun_mode(const snd_pcm_sw_params_t *params)
5007 {
5008         assert(params);
5009         /* FIXME: Ugly */
5010         return params->stop_threshold > 1024 * 1024 ? SND_PCM_XRUN_NONE : SND_PCM_XRUN_STOP;
5011 }
5012
5013 #ifndef DOC_HIDDEN
5014 link_warning(snd_pcm_sw_params_get_xrun_mode, "Warning: xrun_mode is deprecated, consider to use stop_threshold");
5015 #endif
5016
5017 /**
5018  * \brief Set timestamp mode inside a software configuration container
5019  * \param pcm PCM handle
5020  * \param params Software configuration container
5021  * \param val Timestamp mode
5022  * \return 0 otherwise a negative error code
5023  */
5024 #ifndef DOXYGEN
5025 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)
5026 #else
5027 int snd_pcm_sw_params_set_tstamp_mode(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_tstamp_t val)
5028 #endif
5029 {
5030         assert(pcm && params);
5031         assert(val <= SND_PCM_TSTAMP_LAST);
5032         params->tstamp_mode = val;
5033         return 0;
5034 }
5035
5036 /**
5037  * \brief Get timestamp mode from a software configuration container
5038  * \param params Software configuration container
5039  * \return timestamp mode
5040  */
5041 snd_pcm_tstamp_t snd_pcm_sw_params_get_tstamp_mode(const snd_pcm_sw_params_t *params)
5042 {
5043         assert(params);
5044         return params->tstamp_mode;
5045 }
5046
5047
5048 #if 0
5049 int snd_pcm_sw_params_set_period_step(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_sw_params_t *params, unsigned int val)
5050 {
5051         assert(pcm && params);
5052         params->period_step = val;
5053         return 0;
5054 }
5055
5056 unsigned int snd_pcm_sw_params_get_period_step(const snd_pcm_sw_params_t *params)
5057 {
5058         assert(params);
5059         return params->period_step;
5060 }
5061 #endif
5062
5063
5064 /**
5065  * \brief Set minimum number of ticks to sleep inside a software configuration container
5066  * \param pcm PCM handle
5067  * \param params Software configuration container
5068  * \param val Minimum ticks to sleep or 0 to disable the use of tick timer
5069  * \return 0 otherwise a negative error code
5070  */
5071 #ifndef DOXYGEN
5072 int snd_pcm_sw_params_set_sleep_min(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_sw_params_t *params, unsigned int val)
5073 #else
5074 int snd_pcm_sw_params_set_sleep_min(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, unsigned int val)
5075 #endif
5076 {
5077         assert(pcm && params);
5078         params->sleep_min = val;
5079         return 0;
5080 }
5081
5082 /**
5083  * \brief Get minimum numbers of ticks to sleep from a software configuration container
5084  * \param params Software configuration container
5085  * \return minimum number of ticks to sleep or 0 if tick timer is disabled
5086  */
5087 unsigned int snd_pcm_sw_params_get_sleep_min(const snd_pcm_sw_params_t *params)
5088 {
5089         assert(params);
5090         return params->sleep_min;
5091 }
5092
5093 /**
5094  * \brief Set avail min inside a software configuration container
5095  * \param pcm PCM handle
5096  * \param params Software configuration container
5097  * \param val Minimum avail frames to consider PCM ready
5098  * \return 0 otherwise a negative error code
5099  */
5100 #ifndef DOXYGEN
5101 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)
5102 #else
5103 int snd_pcm_sw_params_set_avail_min(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val)
5104 #endif
5105 {
5106         assert(pcm && params);
5107         params->avail_min = val;
5108         return 0;
5109 }
5110
5111 /**
5112  * \brief Get avail min from a software configuration container
5113  * \param params Software configuration container
5114  * \return minimum available frames to consider PCM ready
5115  */
5116 snd_pcm_uframes_t snd_pcm_sw_params_get_avail_min(const snd_pcm_sw_params_t *params)
5117 {
5118         assert(params);
5119         return params->avail_min;
5120 }
5121
5122
5123 /**
5124  * \brief Set xfer align inside a software configuration container
5125  * \param pcm PCM handle
5126  * \param params Software configuration container
5127  * \param val Chunk size (frames are attempted to be transferred in chunks)
5128  * \return 0 otherwise a negative error code
5129  */
5130 #ifndef DOXYGEN
5131 int snd_pcm_sw_params_set_xfer_align(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val)
5132 #else
5133 int snd_pcm_sw_params_set_xfer_align(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val)
5134 #endif
5135 {
5136         assert(pcm && params);
5137         assert(val % pcm->min_align == 0);
5138         params->xfer_align = val;
5139         return 0;
5140 }
5141
5142 /**
5143  * \brief Get xfer align from a software configuration container
5144  * \param params Software configuration container
5145  * \return Chunk size (frames are attempted to be transferred in chunks)
5146  */
5147 snd_pcm_uframes_t snd_pcm_sw_params_get_xfer_align(const snd_pcm_sw_params_t *params)
5148 {
5149         assert(params);
5150         return params->xfer_align;
5151 }
5152
5153
5154 /**
5155  * \brief Set start threshold inside a software configuration container
5156  * \param pcm PCM handle
5157  * \param params Software configuration container
5158  * \param val Start threshold in frames 
5159  * \return 0 otherwise a negative error code
5160  *
5161  * PCM is automatically started when playback frames available to PCM 
5162  * are >= threshold or when requested capture frames are >= threshold
5163  */
5164 #ifndef DOXYGEN
5165 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)
5166 #else
5167 int snd_pcm_sw_params_set_start_threshold(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val)
5168 #endif
5169 {
5170         assert(pcm && params);
5171         params->start_threshold = val;
5172         return 0;
5173 }
5174
5175 /**
5176  * \brief Get start threshold from a software configuration container
5177  * \param params Software configuration container
5178  * \return Start threshold in frames
5179  *
5180  * PCM is automatically started when playback frames available to PCM 
5181  * are >= threshold or when requested capture frames are >= threshold
5182  */
5183 snd_pcm_uframes_t snd_pcm_sw_params_get_start_threshold(const snd_pcm_sw_params_t *params)
5184 {
5185         assert(params);
5186         return params->start_threshold;
5187 }
5188
5189 /**
5190  * \brief Set stop threshold inside a software configuration container
5191  * \param pcm PCM handle
5192  * \param params Software configuration container
5193  * \param val Stop threshold in frames
5194  * \return 0 otherwise a negative error code
5195  *
5196  * PCM is automatically stopped in #SND_PCM_STATE_XRUN state when available
5197  * frames is >= threshold
5198  */
5199 #ifndef DOXYGEN
5200 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)
5201 #else
5202 int snd_pcm_sw_params_set_stop_threshold(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val)
5203 #endif
5204 {
5205         assert(pcm && params);
5206         params->stop_threshold = val;
5207         return 0;
5208 }
5209
5210 /**
5211  * \brief Get stop threshold from a software configuration container
5212  * \param params Software configuration container
5213  * \return Stop threshold in frames
5214  *
5215  * PCM is automatically stopped in #SND_PCM_STATE_XRUN state when available
5216  * frames is >= threshold
5217  */
5218 snd_pcm_uframes_t snd_pcm_sw_params_get_stop_threshold(const snd_pcm_sw_params_t *params)
5219 {
5220         assert(params);
5221         return params->stop_threshold;
5222 }
5223
5224 /**
5225  * \brief Set silence threshold inside a software configuration container
5226  * \param pcm PCM handle
5227  * \param params Software configuration container
5228  * \param val Silence threshold in frames 
5229  * \return 0 otherwise a negative error code
5230  *
5231  * A portion of playback buffer is overwritten with silence (see 
5232  * #snd_pcm_sw_params_set_silence_size) when playback underrun is nearer
5233  * than silence threshold
5234  */
5235 #ifndef DOXYGEN
5236 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)
5237 #else
5238 int snd_pcm_sw_params_set_silence_threshold(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val)
5239 #endif
5240 {
5241         assert(pcm && params);
5242         assert(val + params->silence_size <= pcm->buffer_size);
5243         params->silence_threshold = val;
5244         return 0;
5245 }
5246
5247 /**
5248  * \brief Get silence threshold from a software configuration container
5249  * \param params Software configuration container
5250  * \return Silence threshold in frames
5251  *
5252  * A portion of playback buffer is overwritten with silence (see 
5253  * #snd_pcm_sw_params_get_silence_size) when playback underrun is nearer
5254  * than silence threshold
5255  */
5256 snd_pcm_uframes_t snd_pcm_sw_params_get_silence_threshold(const snd_pcm_sw_params_t *params)
5257 {
5258         assert(params);
5259         return params->silence_threshold;
5260 }
5261
5262
5263 /**
5264  * \brief Set silence size inside a software configuration container
5265  * \param pcm PCM handle
5266  * \param params Software configuration container
5267  * \param val Silence size in frames (0 for disabled)
5268  * \return 0 otherwise a negative error code
5269  *
5270  * A portion of playback buffer is overwritten with silence when playback
5271  * underrun is nearer than silence threshold (see 
5272  * #snd_pcm_sw_params_set_silence_threshold)
5273  */
5274 #ifndef DOXYGEN
5275 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)
5276 #else
5277 int snd_pcm_sw_params_set_silence_size(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val)
5278 #endif
5279 {
5280         assert(pcm && params);
5281         assert(val + params->silence_threshold <= pcm->buffer_size);
5282         params->silence_size = val;
5283         return 0;
5284 }
5285
5286 /**
5287  * \brief Get silence size from a software configuration container
5288  * \param params Software configuration container
5289  * \return Silence size in frames (0 for disabled)
5290  *
5291  * A portion of playback buffer is overwritten with silence when playback
5292  * underrun is nearer than silence threshold (see 
5293  * #snd_pcm_sw_params_set_silence_threshold)
5294  */
5295 snd_pcm_uframes_t snd_pcm_sw_params_get_silence_size(const snd_pcm_sw_params_t *params)
5296 {
5297         assert(params);
5298         return params->silence_size;
5299 }
5300
5301
5302 /**
5303  * \brief get size of #snd_pcm_status_t
5304  * \return size in bytes
5305  */
5306 size_t snd_pcm_status_sizeof()
5307 {
5308         return sizeof(snd_pcm_status_t);
5309 }
5310
5311 /**
5312  * \brief allocate an invalid #snd_pcm_status_t using standard malloc
5313  * \param ptr returned pointer
5314  * \return 0 on success otherwise negative error code
5315  */
5316 int snd_pcm_status_malloc(snd_pcm_status_t **ptr)
5317 {
5318         assert(ptr);
5319         *ptr = calloc(1, sizeof(snd_pcm_status_t));
5320         if (!*ptr)
5321                 return -ENOMEM;
5322         return 0;
5323 }
5324
5325 /**
5326  * \brief frees a previously allocated #snd_pcm_status_t
5327  * \param pointer to object to free
5328  */
5329 void snd_pcm_status_free(snd_pcm_status_t *obj)
5330 {
5331         free(obj);
5332 }
5333
5334 /**
5335  * \brief copy one #snd_pcm_status_t to another
5336  * \param dst pointer to destination
5337  * \param src pointer to source
5338  */
5339 void snd_pcm_status_copy(snd_pcm_status_t *dst, const snd_pcm_status_t *src)
5340 {
5341         assert(dst && src);
5342         *dst = *src;
5343 }
5344
5345 /** 
5346  * \brief Get state from a PCM status container (see #snd_pcm_state)
5347  * \return PCM state
5348  */
5349 snd_pcm_state_t snd_pcm_status_get_state(const snd_pcm_status_t *obj)
5350 {
5351         assert(obj);
5352         return obj->state;
5353 }
5354
5355 /** 
5356  * \brief Get trigger timestamp from a PCM status container
5357  * \param ptr Pointer to returned timestamp
5358  */
5359 void snd_pcm_status_get_trigger_tstamp(const snd_pcm_status_t *obj, snd_timestamp_t *ptr)
5360 {
5361         assert(obj && ptr);
5362         *ptr = obj->trigger_tstamp;
5363 }
5364
5365 /** 
5366  * \brief Get "now" timestamp from a PCM status container
5367  * \param ptr Pointer to returned timestamp
5368  */
5369 void snd_pcm_status_get_tstamp(const snd_pcm_status_t *obj, snd_timestamp_t *ptr)
5370 {
5371         assert(obj && ptr);
5372         *ptr = obj->tstamp;
5373 }
5374
5375 /** 
5376  * \brief Get delay from a PCM status container (see #snd_pcm_delay)
5377  * \return Delay in frames
5378  *
5379  * Delay is distance between current application frame position and
5380  * sound frame position.
5381  * It's positive and less than buffer size in normal situation,
5382  * negative on playback underrun and greater than buffer size on
5383  * capture overrun.
5384  */
5385 snd_pcm_sframes_t snd_pcm_status_get_delay(const snd_pcm_status_t *obj)
5386 {
5387         assert(obj);
5388         return obj->delay;
5389 }
5390
5391 /** 
5392  * \brief Get number of frames available from a PCM status container (see #snd_pcm_avail_update)
5393  * \return Number of frames ready to be read/written
5394  */
5395 snd_pcm_uframes_t snd_pcm_status_get_avail(const snd_pcm_status_t *obj)
5396 {
5397         assert(obj);
5398         return obj->avail;
5399 }
5400
5401 /** 
5402  * \brief Get maximum number of frames available from a PCM status container after last #snd_pcm_status call
5403  * \return Maximum number of frames ready to be read/written
5404  */
5405 snd_pcm_uframes_t snd_pcm_status_get_avail_max(const snd_pcm_status_t *obj)
5406 {
5407         assert(obj);
5408         return obj->avail_max;
5409 }
5410
5411 /** 
5412  * \brief Get count of ADC overrange detections since last call
5413  * \return Count of ADC overrange detections
5414  */
5415 snd_pcm_uframes_t snd_pcm_status_get_overrange(const snd_pcm_status_t *obj)
5416 {
5417         assert(obj);
5418         return obj->overrange;
5419 }
5420
5421 /**
5422  * \brief get size of #snd_pcm_info_t
5423  * \return size in bytes
5424  */
5425 size_t snd_pcm_info_sizeof()
5426 {
5427         return sizeof(snd_pcm_info_t);
5428 }
5429
5430 /**
5431  * \brief allocate an invalid #snd_pcm_info_t using standard malloc
5432  * \param ptr returned pointer
5433  * \return 0 on success otherwise negative error code
5434  */
5435 int snd_pcm_info_malloc(snd_pcm_info_t **ptr)
5436 {
5437         assert(ptr);
5438         *ptr = calloc(1, sizeof(snd_pcm_info_t));
5439         if (!*ptr)
5440                 return -ENOMEM;
5441         return 0;
5442 }
5443
5444 /**
5445  * \brief frees a previously allocated #snd_pcm_info_t
5446  * \param pointer to object to free
5447  */
5448 void snd_pcm_info_free(snd_pcm_info_t *obj)
5449 {
5450         free(obj);
5451 }
5452
5453 /**
5454  * \brief copy one #snd_pcm_info_t to another
5455  * \param dst pointer to destination
5456  * \param src pointer to source
5457  */
5458 void snd_pcm_info_copy(snd_pcm_info_t *dst, const snd_pcm_info_t *src)
5459 {
5460         assert(dst && src);
5461         *dst = *src;
5462 }
5463
5464 /**
5465  * \brief Get device from a PCM info container
5466  * \param obj PCM info container
5467  * \return device number
5468  */
5469 unsigned int snd_pcm_info_get_device(const snd_pcm_info_t *obj)
5470 {
5471         assert(obj);
5472         return obj->device;
5473 }
5474
5475 /**
5476  * \brief Get subdevice from a PCM info container
5477  * \param obj PCM info container
5478  * \return subdevice number
5479  */
5480 unsigned int snd_pcm_info_get_subdevice(const snd_pcm_info_t *obj)
5481 {
5482         assert(obj);
5483         return obj->subdevice;
5484 }
5485
5486 /**
5487  * \brief Get stream (direction) from a PCM info container
5488  * \param obj PCM info container
5489  * \return stream
5490  */
5491 snd_pcm_stream_t snd_pcm_info_get_stream(const snd_pcm_info_t *obj)
5492 {
5493         assert(obj);
5494         return obj->stream;
5495 }
5496
5497 /**
5498  * \brief Get card from a PCM info container
5499  * \param obj PCM info container
5500  * \return card number otherwise a negative error code if not associable to a card
5501  */
5502 int snd_pcm_info_get_card(const snd_pcm_info_t *obj)
5503 {
5504         assert(obj);
5505         return obj->card;
5506 }
5507
5508 /**
5509  * \brief Get id from a PCM info container
5510  * \param obj PCM info container
5511  * \return short id of PCM
5512  */
5513 const char *snd_pcm_info_get_id(const snd_pcm_info_t *obj)
5514 {
5515         assert(obj);
5516         return obj->id;
5517 }
5518
5519 /**
5520  * \brief Get name from a PCM info container
5521  * \param obj PCM info container
5522  * \return name of PCM
5523  */
5524 const char *snd_pcm_info_get_name(const snd_pcm_info_t *obj)
5525 {
5526         assert(obj);
5527         return obj->name;
5528 }
5529
5530 /**
5531  * \brief Get subdevice name from a PCM info container
5532  * \param obj PCM info container
5533  * \return name of used PCM subdevice
5534  */
5535 const char *snd_pcm_info_get_subdevice_name(const snd_pcm_info_t *obj)
5536 {
5537         assert(obj);
5538         return obj->subname;
5539 }
5540
5541 /**
5542  * \brief Get class from a PCM info container
5543  * \param obj PCM info container
5544  * \return class of PCM
5545  */
5546 snd_pcm_class_t snd_pcm_info_get_class(const snd_pcm_info_t *obj)
5547 {
5548         assert(obj);
5549         return obj->dev_class;
5550 }
5551
5552 /**
5553  * \brief Get subclass from a PCM info container
5554  * \param obj PCM info container
5555  * \return subclass of PCM
5556  */
5557 snd_pcm_subclass_t snd_pcm_info_get_subclass(const snd_pcm_info_t *obj)
5558 {
5559         assert(obj);
5560         return obj->dev_subclass;
5561 }
5562
5563 /**
5564  * \brief Get subdevices count from a PCM info container
5565  * \param obj PCM info container
5566  * \return subdevices total count of PCM
5567  */
5568 unsigned int snd_pcm_info_get_subdevices_count(const snd_pcm_info_t *obj)
5569 {
5570         assert(obj);
5571         return obj->subdevices_count;
5572 }
5573
5574 /**
5575  * \brief Get available subdevices count from a PCM info container
5576  * \param obj PCM info container
5577  * \return available subdevices count of PCM
5578  */
5579 unsigned int snd_pcm_info_get_subdevices_avail(const snd_pcm_info_t *obj)
5580 {
5581         assert(obj);
5582         return obj->subdevices_avail;
5583 }
5584
5585 /**
5586  * \brief Get hardware synchronization ID from a PCM info container
5587  * \param obj PCM info container
5588  * \return hardware synchronization ID
5589  */
5590 snd_pcm_sync_id_t snd_pcm_info_get_sync(const snd_pcm_info_t *obj)
5591 {
5592         snd_pcm_sync_id_t res;
5593         assert(obj);
5594         memcpy(&res, &obj->sync, sizeof(res));
5595         return res;
5596 }
5597
5598 /**
5599  * \brief Set wanted device inside a PCM info container (see #snd_ctl_pcm_info)
5600  * \param obj PCM info container
5601  * \param val Device number
5602  */
5603 void snd_pcm_info_set_device(snd_pcm_info_t *obj, unsigned int val)
5604 {
5605         assert(obj);
5606         obj->device = val;
5607 }
5608
5609 /**
5610  * \brief Set wanted subdevice inside a PCM info container (see #snd_ctl_pcm_info)
5611  * \param obj PCM info container
5612  * \param val Subdevice number
5613  */
5614 void snd_pcm_info_set_subdevice(snd_pcm_info_t *obj, unsigned int val)
5615 {
5616         assert(obj);
5617         obj->subdevice = val;
5618 }
5619
5620 /**
5621  * \brief Set wanted stream inside a PCM info container (see #snd_ctl_pcm_info)
5622  * \param obj PCM info container
5623  * \param val Stream
5624  */
5625 void snd_pcm_info_set_stream(snd_pcm_info_t *obj, snd_pcm_stream_t val)
5626 {
5627         assert(obj);
5628         obj->stream = val;
5629 }
5630
5631 /**
5632  * \brief Application request to access a portion of direct (mmap) area
5633  * \param pcm PCM handle 
5634  * \param areas Returned mmap channel areas
5635  * \param offset Returned mmap area offset in area steps (== frames)
5636  * \param frames mmap area portion size in frames (wanted on entry, contiguous available on exit)
5637  * \return 0 on success otherwise a negative error code
5638  *
5639  * It is necessary to call the snd_pcm_avail_update() function directly before
5640  * this call. Otherwise, this function can return a wrong count of available frames.
5641  *
5642  * The function should be called before a sample-direct area can be accessed.
5643  * The resulting size parameter is always less or equal to the input count of frames
5644  * and can be zero, if no frames can be processed (the ring buffer is full).
5645  *
5646  * See the snd_pcm_mmap_commit() function to finish the frame processing in
5647  * the direct areas.
5648  * 
5649  */
5650 int snd_pcm_mmap_begin(snd_pcm_t *pcm,
5651                        const snd_pcm_channel_area_t **areas,
5652                        snd_pcm_uframes_t *offset,
5653                        snd_pcm_uframes_t *frames)
5654 {
5655         snd_pcm_uframes_t cont;
5656         snd_pcm_uframes_t f;
5657         snd_pcm_uframes_t avail;
5658         assert(pcm && areas && offset && frames);
5659         if (pcm->stopped_areas &&
5660             snd_pcm_state(pcm) != SND_PCM_STATE_RUNNING) 
5661                 *areas = pcm->stopped_areas;
5662         else
5663                 *areas = pcm->running_areas;
5664         *offset = *pcm->appl.ptr % pcm->buffer_size;
5665         cont = pcm->buffer_size - *offset;
5666         f = *frames;
5667         avail = snd_pcm_mmap_avail(pcm);
5668         if (avail > pcm->buffer_size)
5669                 avail = pcm->buffer_size;
5670         if (f > avail)
5671                 f = avail;
5672         if (f > cont)
5673                 f = cont;
5674         *frames = f;
5675         return 0;
5676 }
5677
5678 /**
5679  * \brief Application has completed the access to area requested with #snd_pcm_mmap_begin
5680  * \param pcm PCM handle
5681  * \param offset area offset in area steps (== frames)
5682  * \param size area portion size in frames
5683  * \return count of transferred frames otherwise a negative error code
5684  *
5685  * You should pass this function the offset value that
5686  * snd_pcm_mmap_begin() returned. The frames parameter should hold the
5687  * number of frames you have written or read to/from the audio
5688  * buffer. The frames parameter must never exceed the contiguous frames
5689  * count that snd_pcm_mmap_begin() returned. Each call to snd_pcm_mmap_begin()
5690  * must be followed by a call to snd_pcm_mmap_commit().
5691  *
5692  * Example:
5693 \code
5694   double phase = 0;
5695   const snd_pcm_area_t *areas;
5696   snd_pcm_sframes_t avail, size, commitres;
5697   snd_pcm_uframes_t offset, frames;
5698   int err;
5699
5700   avail = snd_pcm_avail_update(pcm);
5701   if (avail < 0)
5702     error(avail);
5703   // at this point, we can transfer at least 'avail' frames
5704   
5705   // we want to process frames in chunks (period_size)
5706   if (avail < period_size)
5707     goto _skip;
5708   size = period_size;
5709   // it is possible that contiguous areas are smaller, thus we use a loop
5710   while (size > 0) {
5711     frames = size;
5712
5713     err = snd_pcm_mmap_begin(pcm_handle, &areas, &offset, &frames);
5714     if (err < 0)
5715       error(err);
5716     // this function fills the areas from offset with count of frames
5717     generate_sine(areas, offset, frames, &phase);
5718     commitres = snd_pcm_mmap_commit(pcm_handle, offset, frames);
5719     if (commitres < 0 || commitres != frames)
5720       error(commitres >= 0 ? -EPIPE : commitres);
5721       
5722     size -= frames;
5723   }
5724  _skip:
5725 \endcode
5726  *
5727  * Look to the \ref example_test_pcm "Sine-wave generator" example
5728  * for more details about the generate_sine function.
5729  */
5730 snd_pcm_sframes_t snd_pcm_mmap_commit(snd_pcm_t *pcm,
5731                                       snd_pcm_uframes_t offset,
5732                                       snd_pcm_uframes_t frames)
5733 {
5734         assert(pcm);
5735         assert(offset == *pcm->appl.ptr % pcm->buffer_size);
5736         assert(frames <= snd_pcm_mmap_avail(pcm));
5737         return pcm->fast_ops->mmap_commit(pcm->fast_op_arg, offset, frames);
5738 }
5739
5740 #ifndef DOC_HIDDEN
5741
5742 int _snd_pcm_poll_descriptor(snd_pcm_t *pcm)
5743 {
5744         assert(pcm);
5745         return pcm->poll_fd;
5746 }
5747
5748 void snd_pcm_areas_from_buf(snd_pcm_t *pcm, snd_pcm_channel_area_t *areas, 
5749                             void *buf)
5750 {
5751         unsigned int channel;
5752         unsigned int channels = pcm->channels;
5753         for (channel = 0; channel < channels; ++channel, ++areas) {
5754                 areas->addr = buf;
5755                 areas->first = channel * pcm->sample_bits;
5756                 areas->step = pcm->frame_bits;
5757         }
5758 }
5759
5760 void snd_pcm_areas_from_bufs(snd_pcm_t *pcm, snd_pcm_channel_area_t *areas, 
5761                              void **bufs)
5762 {
5763         unsigned int channel;
5764         unsigned int channels = pcm->channels;
5765         for (channel = 0; channel < channels; ++channel, ++areas, ++bufs) {
5766                 areas->addr = *bufs;
5767                 areas->first = 0;
5768                 areas->step = pcm->sample_bits;
5769         }
5770 }
5771
5772 snd_pcm_sframes_t snd_pcm_read_areas(snd_pcm_t *pcm, const snd_pcm_channel_area_t *areas,
5773                                      snd_pcm_uframes_t offset, snd_pcm_uframes_t size,
5774                                      snd_pcm_xfer_areas_func_t func)
5775 {
5776         snd_pcm_uframes_t xfer = 0;
5777         snd_pcm_sframes_t err = 0;
5778         snd_pcm_state_t state = snd_pcm_state(pcm);
5779
5780         if (size == 0)
5781                 return 0;
5782         if (size > pcm->xfer_align)
5783                 size -= size % pcm->xfer_align;
5784
5785         switch (state) {
5786         case SND_PCM_STATE_PREPARED:
5787                 if (size >= pcm->start_threshold) {
5788                         err = snd_pcm_start(pcm);
5789                         if (err < 0)
5790                                 goto _end;
5791                 }
5792                 break;
5793         case SND_PCM_STATE_DRAINING:
5794         case SND_PCM_STATE_RUNNING:
5795                 break;
5796         case SND_PCM_STATE_XRUN:
5797                 return -EPIPE;
5798         case SND_PCM_STATE_SUSPENDED:
5799                 return -ESTRPIPE;
5800         default:
5801                 return -EBADFD;
5802         }
5803
5804         while (size > 0) {
5805                 snd_pcm_uframes_t frames;
5806                 snd_pcm_sframes_t avail;
5807         _again:
5808                 if (pcm->sleep_min == 0 && state == SND_PCM_STATE_RUNNING) {
5809                         snd_pcm_sframes_t delay;
5810                         /* update hw_ptr */
5811                         err = snd_pcm_delay(pcm, &delay);
5812                         if (err < 0)
5813                                 goto _end;
5814                 }
5815                 avail = snd_pcm_avail_update(pcm);
5816                 if (avail < 0) {
5817                         err = avail;
5818                         goto _end;
5819                 }
5820                 if (((snd_pcm_uframes_t)avail < pcm->avail_min && size > (snd_pcm_uframes_t)avail) ||
5821                     (size >= pcm->xfer_align && (snd_pcm_uframes_t)avail < pcm->xfer_align)) {
5822
5823                         if (pcm->mode & SND_PCM_NONBLOCK) {
5824                                 err = -EAGAIN;
5825                                 goto _end;
5826                         }
5827
5828                         err = snd_pcm_wait(pcm, -1);
5829                         if (err < 0)
5830                                 break;
5831                         state = snd_pcm_state(pcm);
5832                         goto _again;
5833                         
5834                 }
5835                 if ((snd_pcm_uframes_t) avail > pcm->xfer_align)
5836                         avail -= avail % pcm->xfer_align;
5837                 frames = size;
5838                 if (frames > (snd_pcm_uframes_t) avail)
5839                         frames = avail;
5840                 assert(frames != 0);
5841                 err = func(pcm, areas, offset, frames);
5842                 if (err < 0)
5843                         break;
5844                 frames = err;
5845                 offset += frames;
5846                 size -= frames;
5847                 xfer += frames;
5848         }
5849  _end:
5850         return xfer > 0 ? (snd_pcm_sframes_t) xfer : err;
5851 }
5852
5853 snd_pcm_sframes_t snd_pcm_write_areas(snd_pcm_t *pcm, const snd_pcm_channel_area_t *areas,
5854                                       snd_pcm_uframes_t offset, snd_pcm_uframes_t size,
5855                                       snd_pcm_xfer_areas_func_t func)
5856 {
5857         snd_pcm_uframes_t xfer = 0;
5858         snd_pcm_sframes_t err = 0;
5859         snd_pcm_state_t state = snd_pcm_state(pcm);
5860
5861         if (size == 0)
5862                 return 0;
5863         if (size > pcm->xfer_align)
5864                 size -= size % pcm->xfer_align;
5865
5866         switch (state) {
5867         case SND_PCM_STATE_PREPARED:
5868         case SND_PCM_STATE_RUNNING:
5869                 break;
5870         case SND_PCM_STATE_XRUN:
5871                 return -EPIPE;
5872         case SND_PCM_STATE_SUSPENDED:
5873                 return -ESTRPIPE;
5874         default:
5875                 return -EBADFD;
5876         }
5877
5878         while (size > 0) {
5879                 snd_pcm_uframes_t frames;
5880                 snd_pcm_sframes_t avail;
5881         _again:
5882                 if (pcm->sleep_min == 0 && state == SND_PCM_STATE_RUNNING) {
5883                         snd_pcm_sframes_t delay;
5884                         /* update hw_ptr */
5885                         err = snd_pcm_delay(pcm, &delay);
5886                         if (err < 0)
5887                                 goto _end;
5888                 }
5889                 avail = snd_pcm_avail_update(pcm);
5890                 if (avail < 0) {
5891                         err = avail;
5892                         goto _end;
5893                 } else if (((snd_pcm_uframes_t)avail < pcm->avail_min && size > (snd_pcm_uframes_t)avail) ||
5894                            (size >= pcm->xfer_align && (snd_pcm_uframes_t)avail < pcm->xfer_align)) {
5895
5896                         if (pcm->mode & SND_PCM_NONBLOCK) {
5897                                 err = -EAGAIN;
5898                                 goto _end;
5899                         }
5900
5901                         err = snd_pcm_wait(pcm, -1);
5902                         if (err < 0)
5903                                 break;
5904                         state = snd_pcm_state(pcm);
5905                         goto _again;
5906                         
5907                 }
5908                 if ((snd_pcm_uframes_t) avail > pcm->xfer_align)
5909                         avail -= avail % pcm->xfer_align;
5910                 frames = size;
5911                 if (frames > (snd_pcm_uframes_t) avail)
5912                         frames = avail;
5913                 assert(frames != 0);
5914                 err = func(pcm, areas, offset, frames);
5915                 if (err < 0)
5916                         break;
5917                 frames = err;
5918                 offset += frames;
5919                 size -= frames;
5920                 xfer += frames;
5921                 if (state == SND_PCM_STATE_PREPARED) {
5922                         snd_pcm_sframes_t hw_avail = pcm->buffer_size - avail;
5923                         hw_avail += frames;
5924                         /* some plugins might automatically start the stream */
5925                         state = snd_pcm_state(pcm);
5926                         if (state == SND_PCM_STATE_PREPARED &&
5927                             hw_avail >= (snd_pcm_sframes_t) pcm->start_threshold) {
5928                                 err = snd_pcm_start(pcm);
5929                                 if (err < 0)
5930                                         goto _end;
5931                         }
5932                 }
5933         }
5934  _end:
5935         return xfer > 0 ? (snd_pcm_sframes_t) xfer : err;
5936 }
5937
5938 snd_pcm_uframes_t _snd_pcm_mmap_hw_ptr(snd_pcm_t *pcm)
5939 {
5940         return *pcm->hw.ptr;
5941 }
5942
5943 snd_pcm_uframes_t _snd_pcm_boundary(snd_pcm_t *pcm)
5944 {
5945         return pcm->boundary;
5946 }
5947
5948 static const char *names[SND_PCM_HW_PARAM_LAST_INTERVAL + 1] = {
5949         [SND_PCM_HW_PARAM_FORMAT] = "format",
5950         [SND_PCM_HW_PARAM_CHANNELS] = "channels",
5951         [SND_PCM_HW_PARAM_RATE] = "rate",
5952         [SND_PCM_HW_PARAM_PERIOD_TIME] = "period_time",
5953         [SND_PCM_HW_PARAM_BUFFER_TIME] = "buffer_time"
5954 };
5955
5956 int snd_pcm_slave_conf(snd_config_t *root, snd_config_t *conf,
5957                        snd_config_t **_pcm_conf, unsigned int count, ...)
5958 {
5959         snd_config_iterator_t i, next;
5960         const char *str;
5961         struct {
5962                 unsigned int index;
5963                 int flags;
5964                 void *ptr;
5965                 int present;
5966         } fields[count];
5967         unsigned int k;
5968         snd_config_t *pcm_conf = NULL;
5969         int err;
5970         int to_free = 0;
5971         va_list args;
5972         assert(root);
5973         assert(conf);
5974         assert(_pcm_conf);
5975         if (snd_config_get_string(conf, &str) >= 0) {
5976                 err = snd_config_search_definition(root, "pcm_slave", str, &conf);
5977                 if (err < 0) {
5978                         SNDERR("Invalid slave definition");
5979                         return -EINVAL;
5980                 }
5981                 to_free = 1;
5982         }
5983         if (snd_config_get_type(conf) != SND_CONFIG_TYPE_COMPOUND) {
5984                 SNDERR("Invalid slave definition");
5985                 err = -EINVAL;
5986                 goto _err;
5987         }
5988         va_start(args, count);
5989         for (k = 0; k < count; ++k) {
5990                 fields[k].index = va_arg(args, int);
5991                 fields[k].flags = va_arg(args, int);
5992                 fields[k].ptr = va_arg(args, void *);
5993                 fields[k].present = 0;
5994         }
5995         va_end(args);
5996         snd_config_for_each(i, next, conf) {
5997                 snd_config_t *n = snd_config_iterator_entry(i);
5998                 const char *id;
5999                 if (snd_config_get_id(n, &id) < 0)
6000                         continue;
6001                 if (strcmp(id, "comment") == 0)
6002                         continue;
6003                 if (strcmp(id, "pcm") == 0) {
6004                         if (pcm_conf != NULL)
6005                                 snd_config_delete(pcm_conf);
6006                         if ((err = snd_config_copy(&pcm_conf, n)) < 0)
6007                                 goto _err;
6008                         continue;
6009                 }
6010                 for (k = 0; k < count; ++k) {
6011                         unsigned int idx = fields[k].index;
6012                         long v;
6013                         assert(idx < SND_PCM_HW_PARAM_LAST_INTERVAL);
6014                         assert(names[idx]);
6015                         if (strcmp(id, names[idx]) != 0)
6016                                 continue;
6017                         switch (idx) {
6018                         case SND_PCM_HW_PARAM_FORMAT:
6019                         {
6020                                 snd_pcm_format_t f;
6021                                 err = snd_config_get_string(n, &str);
6022                                 if (err < 0) {
6023                                 _invalid:
6024                                         SNDERR("invalid type for %s", id);
6025                                         goto _err;
6026                                 }
6027                                 if ((fields[k].flags & SCONF_UNCHANGED) &&
6028                                     strcasecmp(str, "unchanged") == 0) {
6029                                         *(snd_pcm_format_t*)fields[k].ptr = (snd_pcm_format_t) -2;
6030                                         break;
6031                                 }
6032                                 f = snd_pcm_format_value(str);
6033                                 if (f == SND_PCM_FORMAT_UNKNOWN) {
6034                                         SNDERR("unknown format %s", str);
6035                                         err = -EINVAL;
6036                                         goto _err;
6037                                 }
6038                                 *(snd_pcm_format_t*)fields[k].ptr = f;
6039                                 break;
6040                         }
6041                         default:
6042                                 if ((fields[k].flags & SCONF_UNCHANGED)) {
6043                                         err = snd_config_get_string(n, &str);
6044                                         if (err >= 0 &&
6045                                             strcasecmp(str, "unchanged") == 0) {
6046                                                 *(int*)fields[k].ptr = -2;
6047                                                 break;
6048                                         }
6049                                 }
6050                                 err = snd_config_get_integer(n, &v);
6051                                 if (err < 0)
6052                                         goto _invalid;
6053                                 *(int*)fields[k].ptr = v;
6054                                 break;
6055                         }
6056                         fields[k].present = 1;
6057                         break;
6058                 }
6059                 if (k < count)
6060                         continue;
6061                 SNDERR("Unknown field %s", id);
6062                 err = -EINVAL;
6063                 goto _err;
6064         }
6065         if (!pcm_conf) {
6066                 SNDERR("missing field pcm");
6067                 err = -EINVAL;
6068                 goto _err;
6069         }
6070         for (k = 0; k < count; ++k) {
6071                 if ((fields[k].flags & SCONF_MANDATORY) && !fields[k].present) {
6072                         SNDERR("missing field %s", names[fields[k].index]);
6073                         err = -EINVAL;
6074                         goto _err;
6075                 }
6076         }
6077         *_pcm_conf = pcm_conf;
6078         pcm_conf = NULL;
6079         err = 0;
6080  _err:
6081         if (pcm_conf)
6082                 snd_config_delete(pcm_conf);
6083         if (to_free)
6084                 snd_config_delete(conf);
6085         return err;
6086 }
6087                 
6088
6089 int snd_pcm_conf_generic_id(const char *id)
6090 {
6091         static const char *ids[] = { "comment", "type" };
6092         unsigned int k;
6093         for (k = 0; k < sizeof(ids) / sizeof(ids[0]); ++k) {
6094                 if (strcmp(id, ids[k]) == 0)
6095                         return 1;
6096         }
6097         return 0;
6098 }
6099
6100 static void snd_pcm_set_ptr(snd_pcm_t *pcm, snd_pcm_rbptr_t *rbptr,
6101                             volatile snd_pcm_uframes_t *hw_ptr, int fd, off_t offset)
6102 {
6103         rbptr->master = NULL;   /* I'm master */
6104         rbptr->ptr = hw_ptr;
6105         rbptr->fd = fd;
6106         rbptr->offset = offset;
6107         if (rbptr->changed)
6108                 rbptr->changed(pcm, NULL);
6109 }
6110
6111 void snd_pcm_set_hw_ptr(snd_pcm_t *pcm, volatile snd_pcm_uframes_t *hw_ptr, int fd, off_t offset)
6112 {
6113         assert(pcm);
6114         assert(hw_ptr);
6115         snd_pcm_set_ptr(pcm, &pcm->hw, hw_ptr, fd, offset);
6116 }
6117
6118 void snd_pcm_set_appl_ptr(snd_pcm_t *pcm, volatile snd_pcm_uframes_t *appl_ptr, int fd, off_t offset)
6119 {
6120         assert(pcm);
6121         assert(appl_ptr);
6122         snd_pcm_set_ptr(pcm, &pcm->appl, appl_ptr, fd, offset);
6123 }
6124
6125 static void snd_pcm_link_ptr(snd_pcm_t *pcm, snd_pcm_rbptr_t *pcm_rbptr,
6126                              snd_pcm_t *slave, snd_pcm_rbptr_t *slave_rbptr)
6127 {
6128         snd_pcm_t **a;
6129         int idx;
6130         
6131         a = slave_rbptr->link_dst;
6132         for (idx = 0; idx < slave_rbptr->link_dst_count; idx++)
6133                 if (a[idx] == NULL) {
6134                         a[idx] = pcm;
6135                         goto __found_free_place;
6136                 }
6137         a = realloc(a, sizeof(snd_pcm_t *) * (slave_rbptr->link_dst_count + 1));
6138         if (a == NULL) {
6139                 pcm_rbptr->ptr = NULL;
6140                 pcm_rbptr->fd = -1;
6141                 pcm_rbptr->offset = 0UL;
6142                 return;
6143         }
6144         a[slave_rbptr->link_dst_count++] = pcm;
6145       __found_free_place:
6146         pcm_rbptr->master = slave_rbptr->master ? slave_rbptr->master : slave;
6147         pcm_rbptr->ptr = slave_rbptr->ptr;
6148         pcm_rbptr->fd = slave_rbptr->fd;
6149         pcm_rbptr->offset = slave_rbptr->offset;
6150         slave_rbptr->link_dst = a;
6151         if (pcm_rbptr->changed)
6152                 pcm_rbptr->changed(pcm, slave);
6153 }
6154
6155 static void snd_pcm_unlink_ptr(snd_pcm_t *pcm, snd_pcm_rbptr_t *pcm_rbptr,
6156                                snd_pcm_t *slave, snd_pcm_rbptr_t *slave_rbptr)
6157 {
6158         snd_pcm_t **a;
6159         int idx;
6160
6161         a = slave_rbptr->link_dst;
6162         for (idx = 0; idx < slave_rbptr->link_dst_count; idx++)
6163                 if (a[idx] == pcm) {
6164                         a[idx] = NULL;
6165                         goto __found;
6166                 }
6167         assert(0);
6168         return;
6169
6170       __found:
6171         pcm_rbptr->master = NULL;
6172         pcm_rbptr->ptr = NULL;
6173         pcm_rbptr->fd = -1;
6174         pcm_rbptr->offset = 0UL;
6175         if (pcm_rbptr->changed)
6176                 pcm_rbptr->changed(pcm, slave);
6177 }
6178
6179 void snd_pcm_link_hw_ptr(snd_pcm_t *pcm, snd_pcm_t *slave)
6180 {
6181         assert(pcm);
6182         assert(slave);
6183         snd_pcm_link_ptr(pcm, &pcm->hw, slave, &slave->hw);
6184 }
6185
6186 void snd_pcm_link_appl_ptr(snd_pcm_t *pcm, snd_pcm_t *slave)
6187 {
6188         assert(pcm);
6189         assert(slave);
6190         snd_pcm_link_ptr(pcm, &pcm->appl, slave, &slave->appl);
6191 }
6192
6193 void snd_pcm_unlink_hw_ptr(snd_pcm_t *pcm, snd_pcm_t *slave)
6194 {
6195         assert(pcm);
6196         assert(slave);
6197         snd_pcm_unlink_ptr(pcm, &pcm->hw, slave, &slave->hw);
6198 }
6199
6200 void snd_pcm_unlink_appl_ptr(snd_pcm_t *pcm, snd_pcm_t *slave)
6201 {
6202         assert(pcm);
6203         assert(slave);
6204         snd_pcm_unlink_ptr(pcm, &pcm->appl, slave, &slave->appl);
6205 }
6206
6207 #endif /* DOC_HIDDEN */
6208
6209 /*
6210  *
6211  */
6212
6213 #ifndef DOC_HIDDEN
6214
6215 #ifdef USE_VERSIONED_SYMBOLS
6216
6217 #if 1
6218 /* it's really not so nice: obsolete, but default */
6219 /* forced by developers on alsa-devel */
6220 #define OBSOLETE1(name, what, new) \
6221   symbol_version(__##name, name, new); \
6222   default_symbol_version(__old_##name, name, what);
6223 #else
6224 #define OBSOLETE1(name, what, new) \
6225   default_symbol_version(__##name, name, new); \
6226   symbol_version(__old_##name, name, what);
6227 #endif
6228
6229 #else
6230
6231 #define OBSOLETE1(name, what, new)  /**/
6232
6233 #endif /* USE_VERSIONED_SYMBOLS */
6234
6235 #define __P_OLD_GET(pfx, name, val_type, ret_type) \
6236 ret_type pfx##name(const snd_pcm_hw_params_t *params) \
6237 { \
6238         val_type val; \
6239         if (INTERNAL(name)(params, &val) < 0) \
6240                 return 0; \
6241         return (ret_type)val; \
6242 }
6243
6244 #define __P_OLD_GET1(pfx, name, val_type, ret_type) \
6245 ret_type pfx##name(const snd_pcm_hw_params_t *params, int *dir) \
6246 { \
6247         val_type val; \
6248         if (INTERNAL(name)(params, &val, dir) < 0) \
6249                 return 0; \
6250         return (ret_type)val; \
6251 }
6252
6253 #ifdef USE_VERSIONED_SYMBOLS
6254 #define __OLD_GET(name, val_type, ret_type) __P_OLD_GET(__old_, name, val_type, ret_type)
6255 #define __OLD_GET1(name, val_type, ret_type) __P_OLD_GET1(__old_, name, val_type, ret_type)
6256 #else
6257 #define __OLD_GET(name, val_type, ret_type) __P_OLD_GET(, name, val_type, ret_type)
6258 #define __OLD_GET1(name, val_type, ret_type) __P_OLD_GET1(, name, val_type, ret_type)
6259 #endif
6260
6261 __OLD_GET(snd_pcm_hw_params_get_access, snd_pcm_access_t, int);
6262 __OLD_GET(snd_pcm_hw_params_get_format, snd_pcm_format_t, int);
6263 __OLD_GET(snd_pcm_hw_params_get_subformat, snd_pcm_subformat_t, int);
6264 __OLD_GET(snd_pcm_hw_params_get_channels, unsigned int, int);
6265 __OLD_GET1(snd_pcm_hw_params_get_rate, unsigned int, int);
6266 __OLD_GET1(snd_pcm_hw_params_get_period_time, unsigned int, int);
6267 __OLD_GET1(snd_pcm_hw_params_get_period_size, snd_pcm_uframes_t, snd_pcm_sframes_t);
6268 __OLD_GET1(snd_pcm_hw_params_get_periods, unsigned int, int);
6269 __OLD_GET1(snd_pcm_hw_params_get_buffer_time, unsigned int, int);
6270 __OLD_GET(snd_pcm_hw_params_get_buffer_size, snd_pcm_uframes_t, snd_pcm_sframes_t);
6271 __OLD_GET1(snd_pcm_hw_params_get_tick_time, unsigned int, int);
6272
6273 __OLD_GET(snd_pcm_hw_params_get_channels_min, unsigned int, unsigned int);
6274 __OLD_GET1(snd_pcm_hw_params_get_rate_min, unsigned int, unsigned int);
6275 __OLD_GET1(snd_pcm_hw_params_get_period_time_min, unsigned int, unsigned int);
6276 __OLD_GET1(snd_pcm_hw_params_get_period_size_min, snd_pcm_uframes_t, snd_pcm_uframes_t);
6277 __OLD_GET1(snd_pcm_hw_params_get_periods_min, unsigned int, unsigned int);
6278 __OLD_GET1(snd_pcm_hw_params_get_buffer_time_min, unsigned int, unsigned int);
6279 __OLD_GET(snd_pcm_hw_params_get_buffer_size_min, snd_pcm_uframes_t, snd_pcm_uframes_t);
6280 __OLD_GET1(snd_pcm_hw_params_get_tick_time_min, unsigned int, unsigned int);
6281
6282 __OLD_GET(snd_pcm_hw_params_get_channels_max, unsigned int, unsigned int);
6283 __OLD_GET1(snd_pcm_hw_params_get_rate_max, unsigned int, unsigned int);
6284 __OLD_GET1(snd_pcm_hw_params_get_period_time_max, unsigned int, unsigned int);
6285 __OLD_GET1(snd_pcm_hw_params_get_period_size_max, snd_pcm_uframes_t, snd_pcm_uframes_t);
6286 __OLD_GET1(snd_pcm_hw_params_get_periods_max, unsigned int, unsigned int);
6287 __OLD_GET1(snd_pcm_hw_params_get_buffer_time_max, unsigned int, unsigned int);
6288 __OLD_GET(snd_pcm_hw_params_get_buffer_size_max, snd_pcm_uframes_t, snd_pcm_uframes_t);
6289 __OLD_GET1(snd_pcm_hw_params_get_tick_time_max, unsigned int, unsigned int);
6290
6291 #define __P_OLD_NEAR(pfx, name, ret_type) \
6292 ret_type pfx##name(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, ret_type val) \
6293 { \
6294         if (INTERNAL(name)(pcm, params, &val) < 0) \
6295                 return 0; \
6296         return (ret_type)val; \
6297 }
6298
6299 #define __P_OLD_NEAR1(pfx, name, ret_type) \
6300 ret_type pfx##name(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, ret_type val, int *dir) \
6301 { \
6302         if (INTERNAL(name)(pcm, params, &val, dir) < 0) \
6303                 return 0; \
6304         return (ret_type)val; \
6305 }
6306
6307 #ifdef USE_VERSIONED_SYMBOLS
6308 #define __OLD_NEAR(name, ret_type) __P_OLD_NEAR(__old_, name, ret_type)
6309 #define __OLD_NEAR1(name, ret_type) __P_OLD_NEAR1(__old_, name, ret_type)
6310 #else
6311 #define __OLD_NEAR(name, ret_type) __P_OLD_NEAR(, name, ret_type)
6312 #define __OLD_NEAR1(name, ret_type) __P_OLD_NEAR1(, name, ret_type)
6313 #endif
6314
6315 __OLD_NEAR(snd_pcm_hw_params_set_channels_near, unsigned int);
6316 __OLD_NEAR1(snd_pcm_hw_params_set_rate_near, unsigned int);
6317 __OLD_NEAR1(snd_pcm_hw_params_set_period_time_near, unsigned int);
6318 __OLD_NEAR1(snd_pcm_hw_params_set_period_size_near, snd_pcm_uframes_t);
6319 __OLD_NEAR1(snd_pcm_hw_params_set_periods_near, unsigned int);
6320 __OLD_NEAR1(snd_pcm_hw_params_set_buffer_time_near, unsigned int);
6321 __OLD_NEAR(snd_pcm_hw_params_set_buffer_size_near, snd_pcm_uframes_t);
6322 __OLD_NEAR1(snd_pcm_hw_params_set_tick_time_near, unsigned int);
6323
6324 #define __P_OLD_SET_FL(pfx, name, ret_type) \
6325 ret_type pfx##name(snd_pcm_t *pcm, snd_pcm_hw_params_t *params) \
6326 { \
6327         ret_type val; \
6328         if (INTERNAL(name)(pcm, params, &val) < 0) \
6329                 return 0; \
6330         return (ret_type)val; \
6331 }
6332
6333 #define __P_OLD_SET_FL1(pfx, name, ret_type) \
6334 ret_type pfx##name(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir) \
6335 { \
6336         ret_type val; \
6337         if (INTERNAL(name)(pcm, params, &val, dir) < 0) \
6338                 return 0; \
6339         return (ret_type)val; \
6340 }
6341
6342 #ifdef USE_VERSIONED_SYMBOLS
6343 #define __OLD_SET_FL(name, ret_type) __P_OLD_SET_FL(__old_, name, ret_type)
6344 #define __OLD_SET_FL1(name, ret_type) __P_OLD_SET_FL1(__old_, name, ret_type)
6345 #else
6346 #define __OLD_SET_FL(name, ret_type) __P_OLD_SET_FL(, name, ret_type)
6347 #define __OLD_SET_FL1(name, ret_type) __P_OLD_SET_FL1(, name, ret_type)
6348 #endif
6349
6350 __OLD_SET_FL(snd_pcm_hw_params_set_access_first, snd_pcm_access_t);
6351 __OLD_SET_FL(snd_pcm_hw_params_set_format_first, snd_pcm_format_t);
6352 __OLD_SET_FL(snd_pcm_hw_params_set_subformat_first, snd_pcm_subformat_t);
6353 __OLD_SET_FL(snd_pcm_hw_params_set_channels_first, unsigned int);
6354 __OLD_SET_FL1(snd_pcm_hw_params_set_rate_first, unsigned int);
6355 __OLD_SET_FL1(snd_pcm_hw_params_set_period_time_first, unsigned int);
6356 __OLD_SET_FL1(snd_pcm_hw_params_set_period_size_first, snd_pcm_uframes_t);
6357 __OLD_SET_FL1(snd_pcm_hw_params_set_periods_first, unsigned int);
6358 __OLD_SET_FL1(snd_pcm_hw_params_set_buffer_time_first, unsigned int);
6359 __OLD_SET_FL(snd_pcm_hw_params_set_buffer_size_first, snd_pcm_uframes_t);
6360 __OLD_SET_FL1(snd_pcm_hw_params_set_tick_time_first, unsigned int);
6361
6362 __OLD_SET_FL(snd_pcm_hw_params_set_access_last, snd_pcm_access_t);
6363 __OLD_SET_FL(snd_pcm_hw_params_set_format_last, snd_pcm_format_t);
6364 __OLD_SET_FL(snd_pcm_hw_params_set_subformat_last, snd_pcm_subformat_t);
6365 __OLD_SET_FL(snd_pcm_hw_params_set_channels_last, unsigned int);
6366 __OLD_SET_FL1(snd_pcm_hw_params_set_rate_last, unsigned int);
6367 __OLD_SET_FL1(snd_pcm_hw_params_set_period_time_last, unsigned int);
6368 __OLD_SET_FL1(snd_pcm_hw_params_set_period_size_last, snd_pcm_uframes_t);
6369 __OLD_SET_FL1(snd_pcm_hw_params_set_periods_last, unsigned int);
6370 __OLD_SET_FL1(snd_pcm_hw_params_set_buffer_time_last, unsigned int);
6371 __OLD_SET_FL(snd_pcm_hw_params_set_buffer_size_last, snd_pcm_uframes_t);
6372 __OLD_SET_FL1(snd_pcm_hw_params_set_tick_time_last, unsigned int);
6373
6374 OBSOLETE1(snd_pcm_hw_params_get_access, ALSA_0.9, ALSA_0.9.0rc4);
6375 OBSOLETE1(snd_pcm_hw_params_set_access_first, ALSA_0.9, ALSA_0.9.0rc4);
6376 OBSOLETE1(snd_pcm_hw_params_set_access_last, ALSA_0.9, ALSA_0.9.0rc4);
6377
6378 OBSOLETE1(snd_pcm_hw_params_get_format, ALSA_0.9, ALSA_0.9.0rc4);
6379 OBSOLETE1(snd_pcm_hw_params_set_format_first, ALSA_0.9, ALSA_0.9.0rc4);
6380 OBSOLETE1(snd_pcm_hw_params_set_format_last, ALSA_0.9, ALSA_0.9.0rc4);
6381
6382 OBSOLETE1(snd_pcm_hw_params_get_subformat, ALSA_0.9, ALSA_0.9.0rc4);
6383 OBSOLETE1(snd_pcm_hw_params_set_subformat_first, ALSA_0.9, ALSA_0.9.0rc4);
6384 OBSOLETE1(snd_pcm_hw_params_set_subformat_last, ALSA_0.9, ALSA_0.9.0rc4);
6385
6386 OBSOLETE1(snd_pcm_hw_params_get_channels, ALSA_0.9, ALSA_0.9.0rc4);
6387 OBSOLETE1(snd_pcm_hw_params_get_channels_min, ALSA_0.9, ALSA_0.9.0rc4);
6388 OBSOLETE1(snd_pcm_hw_params_get_channels_max, ALSA_0.9, ALSA_0.9.0rc4);
6389 OBSOLETE1(snd_pcm_hw_params_set_channels_near, ALSA_0.9, ALSA_0.9.0rc4);
6390 OBSOLETE1(snd_pcm_hw_params_set_channels_first, ALSA_0.9, ALSA_0.9.0rc4);
6391 OBSOLETE1(snd_pcm_hw_params_set_channels_last, ALSA_0.9, ALSA_0.9.0rc4);
6392
6393 OBSOLETE1(snd_pcm_hw_params_get_rate, ALSA_0.9, ALSA_0.9.0rc4);
6394 OBSOLETE1(snd_pcm_hw_params_get_rate_min, ALSA_0.9, ALSA_0.9.0rc4);
6395 OBSOLETE1(snd_pcm_hw_params_get_rate_max, ALSA_0.9, ALSA_0.9.0rc4);
6396 OBSOLETE1(snd_pcm_hw_params_set_rate_near, ALSA_0.9, ALSA_0.9.0rc4);
6397 OBSOLETE1(snd_pcm_hw_params_set_rate_first, ALSA_0.9, ALSA_0.9.0rc4);
6398 OBSOLETE1(snd_pcm_hw_params_set_rate_last, ALSA_0.9, ALSA_0.9.0rc4);
6399
6400 OBSOLETE1(snd_pcm_hw_params_get_period_time, ALSA_0.9, ALSA_0.9.0rc4);
6401 OBSOLETE1(snd_pcm_hw_params_get_period_time_min, ALSA_0.9, ALSA_0.9.0rc4);
6402 OBSOLETE1(snd_pcm_hw_params_get_period_time_max, ALSA_0.9, ALSA_0.9.0rc4);
6403 OBSOLETE1(snd_pcm_hw_params_set_period_time_near, ALSA_0.9, ALSA_0.9.0rc4);
6404 OBSOLETE1(snd_pcm_hw_params_set_period_time_first, ALSA_0.9, ALSA_0.9.0rc4);
6405 OBSOLETE1(snd_pcm_hw_params_set_period_time_last, ALSA_0.9, ALSA_0.9.0rc4);
6406
6407 OBSOLETE1(snd_pcm_hw_params_get_period_size, ALSA_0.9, ALSA_0.9.0rc4);
6408 OBSOLETE1(snd_pcm_hw_params_get_period_size_min, ALSA_0.9, ALSA_0.9.0rc4);
6409 OBSOLETE1(snd_pcm_hw_params_get_period_size_max, ALSA_0.9, ALSA_0.9.0rc4);
6410 OBSOLETE1(snd_pcm_hw_params_set_period_size_near, ALSA_0.9, ALSA_0.9.0rc4);
6411 OBSOLETE1(snd_pcm_hw_params_set_period_size_first, ALSA_0.9, ALSA_0.9.0rc4);
6412 OBSOLETE1(snd_pcm_hw_params_set_period_size_last, ALSA_0.9, ALSA_0.9.0rc4);
6413
6414 OBSOLETE1(snd_pcm_hw_params_get_periods, ALSA_0.9, ALSA_0.9.0rc4);
6415 OBSOLETE1(snd_pcm_hw_params_get_periods_min, ALSA_0.9, ALSA_0.9.0rc4);
6416 OBSOLETE1(snd_pcm_hw_params_get_periods_max, ALSA_0.9, ALSA_0.9.0rc4);
6417 OBSOLETE1(snd_pcm_hw_params_set_periods_near, ALSA_0.9, ALSA_0.9.0rc4);
6418 OBSOLETE1(snd_pcm_hw_params_set_periods_first, ALSA_0.9, ALSA_0.9.0rc4);
6419 OBSOLETE1(snd_pcm_hw_params_set_periods_last, ALSA_0.9, ALSA_0.9.0rc4);
6420
6421 OBSOLETE1(snd_pcm_hw_params_get_buffer_time, ALSA_0.9, ALSA_0.9.0rc4);
6422 OBSOLETE1(snd_pcm_hw_params_get_buffer_time_min, ALSA_0.9, ALSA_0.9.0rc4);
6423 OBSOLETE1(snd_pcm_hw_params_get_buffer_time_max, ALSA_0.9, ALSA_0.9.0rc4);
6424 OBSOLETE1(snd_pcm_hw_params_set_buffer_time_near, ALSA_0.9, ALSA_0.9.0rc4);
6425 OBSOLETE1(snd_pcm_hw_params_set_buffer_time_first, ALSA_0.9, ALSA_0.9.0rc4);
6426 OBSOLETE1(snd_pcm_hw_params_set_buffer_time_last, ALSA_0.9, ALSA_0.9.0rc4);
6427
6428 OBSOLETE1(snd_pcm_hw_params_get_buffer_size, ALSA_0.9, ALSA_0.9.0rc4);
6429 OBSOLETE1(snd_pcm_hw_params_get_buffer_size_min, ALSA_0.9, ALSA_0.9.0rc4);
6430 OBSOLETE1(snd_pcm_hw_params_get_buffer_size_max, ALSA_0.9, ALSA_0.9.0rc4);
6431 OBSOLETE1(snd_pcm_hw_params_set_buffer_size_near, ALSA_0.9, ALSA_0.9.0rc4);
6432 OBSOLETE1(snd_pcm_hw_params_set_buffer_size_first, ALSA_0.9, ALSA_0.9.0rc4);
6433 OBSOLETE1(snd_pcm_hw_params_set_buffer_size_last, ALSA_0.9, ALSA_0.9.0rc4);
6434
6435 OBSOLETE1(snd_pcm_hw_params_get_tick_time, ALSA_0.9, ALSA_0.9.0rc4);
6436 OBSOLETE1(snd_pcm_hw_params_get_tick_time_min, ALSA_0.9, ALSA_0.9.0rc4);
6437 OBSOLETE1(snd_pcm_hw_params_get_tick_time_max, ALSA_0.9, ALSA_0.9.0rc4);
6438 OBSOLETE1(snd_pcm_hw_params_set_tick_time_near, ALSA_0.9, ALSA_0.9.0rc4);
6439 OBSOLETE1(snd_pcm_hw_params_set_tick_time_first, ALSA_0.9, ALSA_0.9.0rc4);
6440 OBSOLETE1(snd_pcm_hw_params_set_tick_time_last, ALSA_0.9, ALSA_0.9.0rc4);
6441
6442 #endif /* DOC_HIDDEN */