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