OSDN Git Service

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