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(¶ms->masks[SND_PCM_HW_PARAM_ACCESS - SND_PCM_HW_PARAM_FIRST_MASK], pcm->access); 777 snd_mask_set(¶ms->masks[SND_PCM_HW_PARAM_FORMAT - SND_PCM_HW_PARAM_FIRST_MASK], pcm->format); 778 snd_mask_set(¶ms->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(¶ms->intervals[SND_PCM_HW_PARAM_FRAME_BITS - SND_PCM_HW_PARAM_FIRST_INTERVAL], frame_bits); 781 snd_interval_set_value(¶ms->intervals[SND_PCM_HW_PARAM_CHANNELS - SND_PCM_HW_PARAM_FIRST_INTERVAL], pcm->channels); 782 snd_interval_set_value(¶ms->intervals[SND_PCM_HW_PARAM_RATE - SND_PCM_HW_PARAM_FIRST_INTERVAL], pcm->rate); 783 snd_interval_set_value(¶ms->intervals[SND_PCM_HW_PARAM_PERIOD_TIME - SND_PCM_HW_PARAM_FIRST_INTERVAL], pcm->period_time); 784 snd_interval_set_value(¶ms->intervals[SND_PCM_HW_PARAM_PERIOD_SIZE - SND_PCM_HW_PARAM_FIRST_INTERVAL], pcm->period_size); 785 snd_interval_copy(¶ms->intervals[SND_PCM_HW_PARAM_PERIODS - SND_PCM_HW_PARAM_FIRST_INTERVAL], &pcm->periods); 786 snd_interval_copy(¶ms->intervals[SND_PCM_HW_PARAM_BUFFER_TIME - SND_PCM_HW_PARAM_FIRST_INTERVAL], &pcm->buffer_time); 787 snd_interval_set_value(¶ms->intervals[SND_PCM_HW_PARAM_BUFFER_SIZE - SND_PCM_HW_PARAM_FIRST_INTERVAL], pcm->buffer_size); 788 snd_interval_set_value(¶ms->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(¶ms); 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