OSDN Git Service

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