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