• Home
  • History
  • Annotate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/ap/gpl/iserver/alsa-lib-1.0.26/src/pcm/

Lines Matching defs:*

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
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.
16 * See the \ref pcm page for more details.
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>
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.
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.
33 * You should have received a copy of the GNU Lesser General Public
34 * License along with this library; if not, write to the Free Software
35 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
39 /*! \page pcm PCM (digital audio) interface
41 <P>Although abbreviation PCM stands for Pulse Code Modulation, we are
42 understanding it as general digital audio processing with volume samples
43 generated in continuous time periods.</P>
45 <P>The analog signal is recorded via analog to digital converters (ADC).
46 The digital value (de-facto a volume at a specific time) obtained
47 from ADC can be further processed. The following picture shows a perfect
48 sinus waveform:</P>
50 <BR>
51 \image html wave1.gif
53 <P>Next image shows digitized representation:</P>
55 <BR>
56 \image html wave2.gif
58 <P>As you may see, the quality of digital audio signal depends on the time
59 (recording rate) and voltage resolution (usually in an linear integer
60 representation with basic unit one bit).</P>
62 <P>The stored digital signal can be converted back to voltage (analog)
63 representation via digital to analog converters (DAC).</P>
65 <P>One digital value is called sample. More samples are collected to frames
66 (frame is terminology for ALSA) depending on count of converters used at one
67 specific time. One frame might contain one sample (when only one converter is
68 used - mono) or more samples (for example: stereo has signals from two converters
69 recorded at same time). Digital audio stream contains collection of frames
70 recorded at boundaries of continuous time periods.</P>
72 \section pcm_general_overview General overview
74 ALSA uses the ring buffer to store outgoing (playback) and incoming (capture,
75 record) samples. There are two pointers being maintained to allow
76 a precise communication between application and device pointing to current
77 processed sample by hardware and last processed sample by application.
78 The modern audio chips allow to program the transfer time periods.
79 It means that the stream of samples is divided to small chunks. Device
80 acknowledges to application when the transfer of a chunk is complete.
82 \section pcm_transfer Transfer methods in UNIX environments
84 In the UNIX environment, data chunk acknowledges are received via standard I/O
85 calls or event waiting routines (poll or select function). To accomplish
86 this list, the asynchronous notification of acknowledges should be listed
87 here. The ALSA implementation for these methods is described in
88 the \ref alsa_transfers section.
90 \subsection pcm_transfer_io Standard I/O transfers
92 The standard I/O transfers are using the read (see 'man 2 read') and write
93 (see 'man 2 write') C functions. There are two basic behaviours of these
94 functions - blocked and non-blocked (see the O_NONBLOCK flag for the
95 standard C open function - see 'man 2 open'). In non-blocked behaviour,
96 these I/O functions never stops, they return -EAGAIN error code, when no
97 data can be transferred (the ring buffer is full in our case). In blocked
98 behaviour, these I/O functions stop and wait until there is a room in the
99 ring buffer (playback) or until there are a new samples (capture). The ALSA
100 implementation can be found in the \ref alsa_pcm_rw section.
102 \subsection pcm_transfer_event Event waiting routines
104 The poll or select functions (see 'man 2 poll' or 'man 2 select' for further
105 details) allows to receive requests/events from the device while
106 an application is waiting on events from other sources (like keyboard, screen,
107 network etc.), too. \ref snd_pcm_poll_descriptors can be used to get file
108 descriptors to poll or select on (note that wait direction might be diferent
109 than expected - do not use only returned file descriptors, but handle
110 events member as well - see \ref snd_pcm_poll_descriptors function
111 description for more details and \ref snd_pcm_poll_descriptors_revents for
112 events demangling). The implemented transfer routines can be found in
113 the \ref alsa_transfers section.
115 \subsection pcm_transfer_async Asynchronous notification
117 ALSA driver and library knows to handle the asynchronous notifications over
118 the SIGIO signal. This signal allows to interrupt application and transfer
119 data in the signal handler. For further details see the sigaction function
120 ('man 2 sigaction'). The section \ref pcm_async describes the ALSA API for
121 this extension. The implemented transfer routines can be found in the
122 \ref alsa_transfers section.
124 \section pcm_open_behaviour Blocked and non-blocked open
126 The ALSA PCM API uses a different behaviour when the device is opened
127 with blocked or non-blocked mode. The mode can be specified with
128 \a mode argument in #snd_pcm_open() function.
129 The blocked mode is the default (without #SND_PCM_NONBLOCK mode).
130 In this mode, the behaviour is that if the resources have already used
131 with another application, then it blocks the caller, until resources are
132 free. The non-blocked behaviour (with #SND_PCM_NONBLOCK)
133 doesn't block the caller in any way and returns -EBUSY error when the
134 resources are not available. Note that the mode also determines the
135 behaviour of standard I/O calls, returning -EAGAIN when non-blocked mode is
136 used and the ring buffer is full (playback) or empty (capture).
137 The operation mode for I/O calls can be changed later with
138 the #snd_pcm_nonblock() function.
140 \section pcm_async Asynchronous mode
142 There is also possibility to receive asynchronous notification after
143 specified time periods. You may see the #SND_PCM_ASYNC
144 mode for #snd_pcm_open() function and
145 #snd_async_add_pcm_handler() function for further details.
147 \section pcm_handshake Handshake between application and library
149 The ALSA PCM API design uses the states to determine the communication
150 phase between application and library. The actual state can be determined
151 using #snd_pcm_state() call. There are these states:
153 \par SND_PCM_STATE_OPEN
154 The PCM device is in the open state. After the #snd_pcm_open() open call,
155 the device is in this state. Also, when #snd_pcm_hw_params() call fails,
156 then this state is entered to force application calling
157 #snd_pcm_hw_params() function to set right communication
158 parameters.
160 \par SND_PCM_STATE_SETUP
161 The PCM device has accepted communication parameters and it is waiting
162 for #snd_pcm_prepare() call to prepare the hardware for
163 selected operation (playback or capture).
165 \par SND_PCM_STATE_PREPARE
166 The PCM device is prepared for operation. Application can use
167 #snd_pcm_start() call, write or read data to start
168 the operation.
170 \par SND_PCM_STATE_RUNNING
171 The PCM device has been started and is running. It processes the samples. The stream can
172 be stopped using the #snd_pcm_drop() or
173 #snd_pcm_drain() calls.
175 \par SND_PCM_STATE_XRUN
176 The PCM device reached overrun (capture) or underrun (playback).
177 You can use the -EPIPE return code from I/O functions
178 (#snd_pcm_writei(), #snd_pcm_writen(), #snd_pcm_readi(), #snd_pcm_readn())
179 to determine this state without checking
180 the actual state via #snd_pcm_state() call. It is recommended to use
181 the helper function #snd_pcm_recover() to recover from this state, but you can also use #snd_pcm_prepare(),
182 #snd_pcm_drop() or #snd_pcm_drain() calls.
184 \par SND_PCM_STATE_DRAINING
185 The device is in this state when application using the capture mode
186 called #snd_pcm_drain() function. Until all data are
187 read from the internal ring buffer using I/O routines
188 (#snd_pcm_readi(), #snd_pcm_readn()),
189 then the device stays in this state.
191 \par SND_PCM_STATE_PAUSED
192 The device is in this state when application called
193 the #snd_pcm_pause() function until the pause is released.
194 Not all hardware supports this feature. Application should check the
195 capability with the #snd_pcm_hw_params_can_pause().
197 \par SND_PCM_STATE_SUSPENDED
198 The device is in the suspend state provoked with the power management
199 system. The stream can be resumed using #snd_pcm_resume()
200 call, but not all hardware supports this feature. Application should check
201 the capability with the #snd_pcm_hw_params_can_resume().
202 In other case, the calls #snd_pcm_prepare(),
203 #snd_pcm_drop(), #snd_pcm_drain() can be used
204 to leave this state.
206 \par SND_PCM_STATE_DISCONNECTED
207 The device is physicaly disconnected. It does not accept any I/O calls in this state.
209 \section pcm_formats PCM formats
211 The full list of formats present the #snd_pcm_format_t type.
212 The 24-bit linear samples use 32-bit physical space, but the sample is
213 stored in the lower three bytes. Some hardware does not support processing of full
214 range, thus you may get the significant bits for linear samples via
215 #snd_pcm_hw_params_get_sbits() function. The example: ICE1712
216 chips support 32-bit sample processing, but low byte is ignored (playback)
217 or zero (capture). The function snd_pcm_hw_params_get_sbits()
218 returns 24 in this case.
220 \section alsa_transfers ALSA transfers
222 There are two methods to transfer samples in application. The first method
223 is the standard read / write one. The second method, uses the direct audio
224 buffer to communicate with the device while ALSA library manages this space
225 itself. You can find examples of all communication schemes for playback
226 in \ref example_test_pcm "Sine-wave generator example". To complete the
227 list, we should note that #snd_pcm_wait() function contains
228 embedded poll waiting implementation.
230 \subsection alsa_pcm_rw Read / Write transfer
232 There are two versions of read / write routines. The first expects the
233 interleaved samples at input (#SND_PCM_ACCESS_RW_INTERLEAVED access method),
234 and the second one expects non-interleaved (samples in separated buffers -
235 #SND_PCM_ACCESS_RW_NONINTERLEAVED access method) at input. There are these
236 functions for interleaved transfers: #snd_pcm_writei()
237 #snd_pcm_readi(). For non-interleaved transfers, there are
238 these functions: #snd_pcm_writen() and #snd_pcm_readn().
240 \subsection alsa_mmap_rw Direct Read / Write transfer (via mmap'ed areas)
242 Three kinds of organization of ring buffer memory areas exist in ALSA API.
243 Access #SND_PCM_ACCESS_MMAP_INTERLEAVED has interleaved samples. Access
244 #SND_PCM_ACCESS_MMAP_NONINTERLEAVED expects continous sample areas for
245 one channel. Access #SND_PCM_ACCESS_MMAP_COMPLEX does not fit to interleaved
246 and non-interleaved ring buffer organization.
248 There are two functions for this kind of transfer. Application can get an
249 access to memory areas via #snd_pcm_mmap_begin() function.
250 This function returns the areas (single area is equal to a channel)
251 containing the direct pointers to memory and sample position description
252 in #snd_pcm_channel_area_t structure. After application
253 transfers the data in the memory areas, then it must be acknowledged
254 the end of transfer via #snd_pcm_mmap_commit() function
255 to allow the ALSA library update the pointers to ring buffer. This kind of
256 communication is also called "zero-copy", because the device does not require
257 to copy the samples from application to another place in system memory.
259 If you like to use the compatibility functions in mmap mode, there are
260 read / write routines equaling to standard read / write transfers. Using
261 these functions discards the benefits of direct access to memory region.
262 See the #snd_pcm_mmap_readi(),
263 #snd_pcm_writei(), #snd_pcm_readn()
264 and #snd_pcm_writen() functions.
266 \section pcm_errors Error codes
268 \par -EPIPE
270 This error means xrun (underrun for playback or overrun for capture).
271 The underrun can happen when an application does not feed new samples
272 in time to alsa-lib (due CPU usage). The overrun can happen when
273 an application does not take new captured samples in time from alsa-lib.
275 \par -ESTRPIPE
277 This error means that system has suspended drivers. The application
278 should wait in loop when snd_pcm_resume() != -EAGAIN and then
279 call snd_pcm_prepare() when snd_pcm_resume() return an error code.
280 If snd_pcm_resume() does not fail (a zero value is returned), driver
281 supports resume and the snd_pcm_prepare() call can be ommited.
283 \par -EBADFD
285 This error means that the device is in a bad state. It means that
286 the handskahe between application and alsa-lib is corrupted.
288 \par -ENOTTY, -ENODEV
290 This error can happen when device is physically removed (for example
291 some hotplug devices like USB or PCMCIA, CardBus or ExpressCard
292 can be removed on the fly).
294 \section pcm_params Managing parameters
296 The ALSA PCM device uses two groups of PCM related parameters. The hardware
297 parameters contains the stream description like format, rate, count of
298 channels, ring buffer size etc. The software parameters contains the
299 software (driver) related parameters. The communication behaviour can be
300 controlled via these parameters, like automatic start, automatic stop,
301 interrupting (chunk acknowledge) etc. The software parameters can be
302 modified at any time (when valid hardware parameters are set). It includes
303 the running state as well.
305 \subsection pcm_hw_params Hardware related parameters
307 The ALSA PCM devices use the parameter refining system for hardware
308 parameters - #snd_pcm_hw_params_t. It means, that
309 application choose the full-range of configurations at first and then
310 application sets single parameters until all parameters are elementary
311 (definite).
313 \par Access modes
315 ALSA knows about five access modes. The first three can be used for direct
316 communication. The access mode #SND_PCM_ACCESS_MMAP_INTERLEAVED
317 determines the direct memory area and interleaved sample organization.
318 Interleaved organization means, that samples from channels are mixed together.
319 The access mode #SND_PCM_ACCESS_MMAP_NONINTERLEAVED
320 determines the direct memory area and non-interleaved sample organization.
321 Each channel has a separate buffer in the case. The complex direct memory
322 organization represents the #SND_PCM_ACCESS_MMAP_COMPLEX
323 access mode. The sample organization does not fit the interleaved or
324 non-interleaved access modes in the case. The last two access modes
325 describes the read / write access methods.
326 The #SND_PCM_ACCESS_RW_INTERLEAVED access represents the read /
327 write interleaved access and the #SND_PCM_ACCESS_RW_NONINTERLEAVED
328 represents the non-interleaved access.
330 \par Formats
332 The full list of formats is available in #snd_pcm_format_t
333 enumeration.
335 \subsection pcm_sw_params Software related parameters
337 These parameters - #snd_pcm_sw_params_t can be modified at
338 any time including the running state.
340 \par Minimum available count of samples
342 This parameter controls the wakeup point. If the count of available samples
343 is equal or greater than this value, then application will be activated.
345 \par Timestamp mode
347 The timestamp mode specifies, if timestamps are activated. Currently, only
348 #SND_PCM_TSTAMP_NONE and #SND_PCM_TSTAMP_MMAP
349 modes are known. The mmap mode means that timestamp is taken
350 on every period time boundary. Corresponding position in the ring buffer
351 assigned to timestamp can be obtained using #snd_pcm_htimestamp() function.
353 \par Transfer align
355 The read / write transfers can be aligned to this sample count. The modulo
356 is ignored by device. Usually, this value is set to one (no align).
358 \par Start threshold
360 The start threshold parameter is used to determine the start point in
361 stream. For playback, if samples in ring buffer is equal or greater than
362 the start threshold parameters and the stream is not running, the stream will
363 be started automatically from the device. For capture, if the application wants
364 to read count of samples equal or greater then the stream will be started.
365 If you want to use explicit start (#snd_pcm_start), you can
366 set this value greater than ring buffer size (in samples), but use the
367 constant MAXINT is not a bad idea.
369 \par Stop threshold
371 Similarly, the stop threshold parameter is used to automatically stop
372 the running stream, when the available samples crosses this boundary.
373 It means, for playback, the empty samples in ring buffer and for capture,
374 the filled (used) samples in ring buffer.
376 \par Silence threshold
378 The silence threshold specifies count of samples filled with silence
379 ahead of the current application pointer for playback. It is usable
380 for applications when an overrun is possible (like tasks depending on
381 network I/O etc.). If application wants to manage the ahead samples itself,
382 the #snd_pcm_rewind() function allows to forget the last
383 samples in the stream.
385 \section pcm_status Obtaining stream status
387 The stream status is stored in #snd_pcm_status_t structure.
388 These parameters can be obtained: the current stream state -
389 #snd_pcm_status_get_state(), timestamp of trigger -
390 #snd_pcm_status_get_trigger_tstamp(), timestamp of last
391 pointer update #snd_pcm_status_get_tstamp(), delay in samples -
392 #snd_pcm_status_get_delay(), available count in samples -
393 #snd_pcm_status_get_avail(), maximum available samples -
394 #snd_pcm_status_get_avail_max(), ADC over-range count in
395 samples - #snd_pcm_status_get_overrange(). The last two
396 parameters - avail_max and overrange are reset to zero after the status
397 call.
399 \subsection pcm_status_fast Obtaining stream state fast and update r/w pointer
401 <p>
402 The function #snd_pcm_avail_update() updates the current
403 available count of samples for writing (playback) or filled samples for
404 reading (capture). This call is mandatory for updating actual r/w pointer.
405 Using standalone, it is a light method to obtain current stream position,
406 because it does not require the user <-> kernel context switch, but the value
407 is less accurate, because ring buffer pointers are updated in kernel drivers
408 only when an interrupt occurs. If you want to get accurate stream state,
409 use functions #snd_pcm_avail(), #snd_pcm_delay() or #snd_pcm_avail_delay().
410 </p>
411 <p>
412 The function #snd_pcm_avail() reads the current hardware pointer
413 in the ring buffer from hardware and calls #snd_pcm_avail_update() then.
414 </p>
415 <p>
416 The function #snd_pcm_delay() returns the delay in samples.
417 For playback, it means count of samples in the ring buffer before
418 the next sample will be sent to DAC. For capture, it means count of samples
419 in the ring buffer before the next sample will be captured from ADC. It works
420 only when the stream is in the running or draining (playback only) state.
421 Note that this function does not update the current r/w pointer for applications,
422 so the function #snd_pcm_avail_update() must be called afterwards
423 before any read/write begin+commit operations.
424 </p>
425 <p>
426 The function #snd_pcm_avail_delay() combines #snd_pcm_avail() and
427 #snd_pcm_delay() and returns both values in sync.
428 </p>
430 \section pcm_action Managing the stream state
432 The following functions directly and indirectly affect the stream state:
434 \par snd_pcm_hw_params
435 The #snd_pcm_hw_params() function brings the stream state
436 to #SND_PCM_STATE_SETUP
437 if successfully finishes, otherwise the state #SND_PCM_STATE_OPEN
438 is entered.
439 When it is brought to SETUP state, this function automatically
440 calls #snd_pcm_prepare() function to bring to the PREPARE state
441 as below.
443 \par snd_pcm_prepare
444 The #snd_pcm_prepare() function enters from #SND_PCM_STATE_SETUP
445 to the #SND_PCM_STATE_PREPARED after a successful finish.
447 \par snd_pcm_start
448 The #snd_pcm_start() function enters
449 the #SND_PCM_STATE_RUNNING after a successful finish.
451 \par snd_pcm_drop
452 The #snd_pcm_drop() function enters the
453 #SND_PCM_STATE_SETUP state.
455 \par snd_pcm_drain
456 The #snd_pcm_drain() function enters the
457 #SND_PCM_STATE_DRAINING, if
458 the capture device has some samples in the ring buffer otherwise
459 #SND_PCM_STATE_SETUP state is entered.
461 \par snd_pcm_pause
462 The #snd_pcm_pause() function enters the
463 #SND_PCM_STATE_PAUSED or #SND_PCM_STATE_RUNNING.
465 \par snd_pcm_writei, snd_pcm_writen
466 The #snd_pcm_writei() and #snd_pcm_writen()
467 functions can conditionally start the stream -
468 #SND_PCM_STATE_RUNNING. They depend on the start threshold
469 software parameter.
471 \par snd_pcm_readi, snd_pcm_readn
472 The #snd_pcm_readi() and #snd_pcm_readn()
473 functions can conditionally start the stream -
474 #SND_PCM_STATE_RUNNING. They depend on the start threshold
475 software parameter.
477 \section pcm_sync Streams synchronization
479 There are two functions allowing link multiple streams together. In the
480 case, the linking means that all operations are synchronized. Because the
481 drivers cannot guarantee the synchronization (sample resolution) on hardware
482 lacking this feature, the #snd_pcm_info_get_sync() function
483 returns synchronization ID - #snd_pcm_sync_id_t, which is equal
484 for hardware synchronized streams. When the #snd_pcm_link()
485 function is called, all operations managing the stream state for these two
486 streams are joined. The opposite function is #snd_pcm_unlink().
488 \section pcm_dev_names PCM naming conventions
490 The ALSA library uses a generic string representation for names of devices.
491 The devices might be virtual, physical or a mix of both. The generic string
492 is passed to #snd_pcm_open() or #snd_pcm_open_lconf().
493 It contains two parts: device name and arguments. Devices and arguments are described
494 in configuration files. The usual place for default definitions is at /usr/share/alsa/alsa.conf.
495 For detailed descriptions about integrated PCM plugins look to \ref pcm_plugins.
497 \subsection pcm_dev_names_default Default device
499 The default device is equal to plug plugin with hw plugin as slave. The defaults are
500 used:
502 \code
503 defaults.pcm.card 0
504 defaults.pcm.device 0
505 defaults.pcm.subdevice -1
506 \endcode
508 These defaults can be freely overwritten in local configuration files.
510 Example:
512 \code
513 default
514 \endcode
516 \subsection pcm_dev_names_hw HW device
518 The hw device description uses the hw plugin. The three arguments (in order: CARD,DEV,SUBDEV)
519 specify card number or identifier, device number and subdevice number (-1 means any).
521 Example:
523 \code
524 hw
525 hw:0
526 hw:0,0
527 hw:supersonic,1
528 hw:soundwave,1,2
529 hw:DEV=1,CARD=soundwave,SUBDEV=2
530 \endcode
532 \subsection pcm_dev_names_plughw Plug->HW device
534 The plughw device description uses the plug plugin and hw plugin as slave. The arguments
535 are same as for hw device.
537 Example:
539 \code
540 plughw
541 plughw:0
542 plughw:0,0
543 plughw:supersonic,1
544 plughw:soundwave,1,2
545 plughw:DEV=1,CARD=soundwave,SUBDEV=2
546 \endcode
548 \subsection pcm_dev_names_plug Plug device
550 The plug device uses the plug plugin. The one SLAVE argument specifies the slave plugin.
552 Example:
554 \code
555 plug:mypcmdef
556 plug:hw
557 plug:'hw:0,0'
558 plug:SLAVE=hw
559 \endcode
561 \subsection pcm_dev_names_shm Shared memory device
563 The shm device uses the shm plugin. The two arguments (in order: SOCKET,PCM) specify
564 UNIX socket name (for example /tmp/alsa.socket) for server communication and server's PCM name.
566 Example:
568 \code
569 shm:'/tmp/alsa.sock',default
570 shm:SOCKET='/tmp/alsa.sock',PCM=default
571 \endcode
573 \subsection pcm_dev_names_tee Tee device
575 The tee device stores contents of a stream to given file plus transfers it to given slave plugin.
576 The three arguments (in order: SLAVE,FILE,FORMAT) specify slave plugin, filename and file format.
578 Example:
580 \code
581 tee:hw,'/tmp/out.raw',raw
582 \endcode
584 \subsection pcm_dev_names_file File device
586 The file device is file plugin with null plugin as slave. The arguments (in order: FILE,FORMAT)
587 specify filename and file format.
589 Example:
591 \code
592 file:'/tmp/out.raw',raw
593 \endcode
595 \subsection pcm_dev_names_null Null device
597 The null device is null plugin. This device has not any arguments.
600 \section pcm_examples Examples
602 The full featured examples with cross-links can be found in Examples section
603 (see top of page):
605 \anchor example_test_pcm
606 \par Sine-wave generator
607 \par
608 alsa-lib/test/pcm.c example shows various transfer methods for the playback direction.
610 \par Minimalistic PCM playback code
611 \par
612 alsa-lib/test/pcm_min.c example shows the minimal code to produce a sound.
614 \par Latency measuring tool
615 \par
616 alsa-lib/test/latency.c example shows the measuring of minimal latency between capture and
617 playback devices.
622 \example ../../test/pcm.c
625 \example ../../test/pcm_min.c
628 \example ../../test/latency.c
631 #include <stdio.h>
632 #include <string.h>
633 #include <malloc.h>
634 #include <stdarg.h>
635 #include <signal.h>
636 #include <sys/poll.h>
637 #include <sys/shm.h>
638 #include <sys/mman.h>
639 #include <limits.h>
640 #include "pcm_local.h"
643 * \brief get identifier of PCM handle
644 * \param pcm PCM handle
645 * \return ascii identifier of PCM handle
647 * Returns the ASCII identifier of given PCM handle. It's the same
648 * identifier specified in snd_pcm_open().
650 const char *snd_pcm_name(snd_pcm_t *pcm)
652 assert(pcm);
653 return pcm->name;
657 * \brief get type of PCM handle
658 * \param pcm PCM handle
659 * \return type of PCM handle
661 * Returns the type #snd_pcm_type_t of given PCM handle.
663 snd_pcm_type_t snd_pcm_type(snd_pcm_t *pcm)
665 assert(pcm);
666 return pcm->type;
670 * \brief get stream for a PCM handle
671 * \param pcm PCM handle
672 * \return stream of PCM handle
674 * Returns the type #snd_pcm_stream_t of given PCM handle.
676 snd_pcm_stream_t snd_pcm_stream(snd_pcm_t *pcm)
678 assert(pcm);
679 return pcm->stream;
683 * \brief close PCM handle
684 * \param pcm PCM handle
685 * \return 0 on success otherwise a negative error code
687 * Closes the specified PCM handle and frees all associated
688 * resources.
690 int snd_pcm_close(snd_pcm_t *pcm)
692 int res = 0, err;
693 assert(pcm);
694 if (pcm->setup && !pcm->donot_close) {
695 snd_pcm_drop(pcm);
696 err = snd_pcm_hw_free(pcm);
697 if (err < 0)
698 res = err;
700 if (pcm->mmap_channels)
701 snd_pcm_munmap(pcm);
702 while (!list_empty(&pcm->async_handlers)) {
703 snd_async_handler_t *h = list_entry(pcm->async_handlers.next, snd_async_handler_t, hlist);
704 snd_async_del_handler(h);
706 err = pcm->ops->close(pcm->op_arg);
707 if (err < 0)
708 res = err;
709 err = snd_pcm_free(pcm);
710 if (err < 0)
711 res = err;
712 return res;
716 * \brief set nonblock mode
717 * \param pcm PCM handle
718 * \param nonblock 0 = block, 1 = nonblock mode
719 * \return 0 on success otherwise a negative error code
721 int snd_pcm_nonblock(snd_pcm_t *pcm, int nonblock)
723 int err;
724 assert(pcm);
725 if ((err = pcm->ops->nonblock(pcm->op_arg, nonblock)) < 0)
726 return err;
727 if (nonblock)
728 pcm->mode |= SND_PCM_NONBLOCK;
729 else {
730 if (pcm->hw_flags & SND_PCM_HW_PARAMS_NO_PERIOD_WAKEUP)
731 return -EINVAL;
732 pcm->mode &= ~SND_PCM_NONBLOCK;
734 return 0;
737 #ifndef DOC_HIDDEN
739 * \brief set async mode
740 * \param pcm PCM handle
741 * \param sig Signal to raise: < 0 disable, 0 default (SIGIO)
742 * \param pid Process ID to signal: 0 current
743 * \return 0 on success otherwise a negative error code
745 * A signal is raised every period.
747 int snd_pcm_async(snd_pcm_t *pcm, int sig, pid_t pid)
749 assert(pcm);
750 if (sig == 0)
751 sig = SIGIO;
752 if (pid == 0)
753 pid = getpid();
754 return pcm->ops->async(pcm->op_arg, sig, pid);
756 #endif
759 * \brief Obtain general (static) information for PCM handle
760 * \param pcm PCM handle
761 * \param info Information container
762 * \return 0 on success otherwise a negative error code
764 int snd_pcm_info(snd_pcm_t *pcm, snd_pcm_info_t *info)
766 assert(pcm && info);
767 return pcm->ops->info(pcm->op_arg, info);
770 /** \brief Retreive current PCM hardware configuration chosen with #snd_pcm_hw_params
771 * \param pcm PCM handle
772 * \param params Configuration space definition container
773 * \return 0 on success otherwise a negative error code
775 int snd_pcm_hw_params_current(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
777 unsigned int frame_bits;
779 assert(pcm && params);
780 if (!pcm->setup)
781 return -EBADFD;
782 memset(params, 0, snd_pcm_hw_params_sizeof());
783 params->flags = pcm->hw_flags;
784 snd_mask_set(&params->masks[SND_PCM_HW_PARAM_ACCESS - SND_PCM_HW_PARAM_FIRST_MASK], pcm->access);
785 snd_mask_set(&params->masks[SND_PCM_HW_PARAM_FORMAT - SND_PCM_HW_PARAM_FIRST_MASK], pcm->format);
786 snd_mask_set(&params->masks[SND_PCM_HW_PARAM_SUBFORMAT - SND_PCM_HW_PARAM_FIRST_MASK], pcm->subformat);
787 frame_bits = snd_pcm_format_physical_width(pcm->format) * pcm->channels;
788 snd_interval_set_value(&params->intervals[SND_PCM_HW_PARAM_FRAME_BITS - SND_PCM_HW_PARAM_FIRST_INTERVAL], frame_bits);
789 snd_interval_set_value(&params->intervals[SND_PCM_HW_PARAM_CHANNELS - SND_PCM_HW_PARAM_FIRST_INTERVAL], pcm->channels);
790 snd_interval_set_value(&params->intervals[SND_PCM_HW_PARAM_RATE - SND_PCM_HW_PARAM_FIRST_INTERVAL], pcm->rate);
791 snd_interval_set_value(&params->intervals[SND_PCM_HW_PARAM_PERIOD_TIME - SND_PCM_HW_PARAM_FIRST_INTERVAL], pcm->period_time);
792 snd_interval_set_value(&params->intervals[SND_PCM_HW_PARAM_PERIOD_SIZE - SND_PCM_HW_PARAM_FIRST_INTERVAL], pcm->period_size);
793 snd_interval_copy(&params->intervals[SND_PCM_HW_PARAM_PERIODS - SND_PCM_HW_PARAM_FIRST_INTERVAL], &pcm->periods);
794 snd_interval_copy(&params->intervals[SND_PCM_HW_PARAM_BUFFER_TIME - SND_PCM_HW_PARAM_FIRST_INTERVAL], &pcm->buffer_time);
795 snd_interval_set_value(&params->intervals[SND_PCM_HW_PARAM_BUFFER_SIZE - SND_PCM_HW_PARAM_FIRST_INTERVAL], pcm->buffer_size);
796 snd_interval_set_value(&params->intervals[SND_PCM_HW_PARAM_BUFFER_BYTES - SND_PCM_HW_PARAM_FIRST_INTERVAL], (pcm->buffer_size * frame_bits) / 8);
797 params->info = pcm->info;
798 params->msbits = pcm->msbits;
799 params->rate_num = pcm->rate_num;
800 params->rate_den = pcm->rate_den;
801 params->fifo_size = pcm->fifo_size;
802 return 0;
805 /** \brief Install one PCM hardware configuration chosen from a configuration space and #snd_pcm_prepare it
806 * \param pcm PCM handle
807 * \param params Configuration space definition container
808 * \return 0 on success otherwise a negative error code
810 * The configuration is chosen fixing single parameters in this order:
811 * first access, first format, first subformat, min channels, min rate,
812 * min period time, max buffer size, min tick time. If no mutually
813 * compatible set of parameters can be chosen, a negative error code
814 * will be returned.
816 * After this call, #snd_pcm_prepare() is called automatically and
817 * the stream is brought to \c #SND_PCM_STATE_PREPARED state.
819 * The hardware parameters cannot be changed when the stream is
820 * running (active). The software parameters can be changed
821 * at any time.
823 * The configuration space will be updated to reflect the chosen
824 * parameters.
826 int snd_pcm_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
828 int err;
829 assert(pcm && params);
830 err = _snd_pcm_hw_params(pcm, params);
831 if (err < 0)
832 return err;
833 err = snd_pcm_prepare(pcm);
834 return err;
837 /** \brief Remove PCM hardware configuration and free associated resources
838 * \param pcm PCM handle
839 * \return 0 on success otherwise a negative error code
841 int snd_pcm_hw_free(snd_pcm_t *pcm)
843 int err;
844 if (! pcm->setup)
845 return 0;
846 if (pcm->mmap_channels) {
847 err = snd_pcm_munmap(pcm);
848 if (err < 0)
849 return err;
851 // assert(snd_pcm_state(pcm) == SND_PCM_STATE_SETUP ||
852 // snd_pcm_state(pcm) == SND_PCM_STATE_PREPARED);
853 err = pcm->ops->hw_free(pcm->op_arg);
854 pcm->setup = 0;
855 if (err < 0)
856 return err;
857 return 0;
860 /** \brief Install PCM software configuration defined by params
861 * \param pcm PCM handle
862 * \param params Configuration container
863 * \return 0 on success otherwise a negative error code
865 * The software parameters can be changed at any time.
866 * The hardware parameters cannot be changed when the stream is
867 * running (active).
869 int snd_pcm_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t *params)
871 int err;
872 /* the hw_params must be set at first!!! */
873 if (CHECK_SANITY(! pcm->setup)) {
874 SNDMSG("PCM not set up");
875 return -EIO;
877 if (! params->avail_min) {
878 SNDMSG("params->avail_min is 0");
879 return -EINVAL;
881 #if 0
882 /* disable the check below - it looks too restrictive
883 * (start_threshold is basically independent from avail_min)
885 if (params->start_threshold <= pcm->buffer_size &&
886 params->start_threshold > (pcm->buffer_size / params->avail_min) * params->avail_min) {
887 SNDMSG("params->avail_min problem for start_threshold");
888 return -EINVAL;
890 #endif
891 err = pcm->ops->sw_params(pcm->op_arg, params);
892 if (err < 0)
893 return err;
894 pcm->tstamp_mode = params->tstamp_mode;
895 pcm->period_step = params->period_step;
896 pcm->avail_min = params->avail_min;
897 pcm->period_event = params->period_event;
898 pcm->start_threshold = params->start_threshold;
899 pcm->stop_threshold = params->stop_threshold;
900 pcm->silence_threshold = params->silence_threshold;
901 pcm->silence_size = params->silence_size;
902 pcm->boundary = params->boundary;
903 return 0;
907 * \brief Obtain status (runtime) information for PCM handle
908 * \param pcm PCM handle
909 * \param status Status container
910 * \return 0 on success otherwise a negative error code
912 int snd_pcm_status(snd_pcm_t *pcm, snd_pcm_status_t *status)
914 assert(pcm && status);
915 return pcm->fast_ops->status(pcm->fast_op_arg, status);
919 * \brief Return PCM state
920 * \param pcm PCM handle
921 * \return PCM state #snd_pcm_state_t of given PCM handle
923 * This is a faster way to obtain only the PCM state without calling
924 * \link ::snd_pcm_status() \endlink.
926 snd_pcm_state_t snd_pcm_state(snd_pcm_t *pcm)
928 assert(pcm);
929 return pcm->fast_ops->state(pcm->fast_op_arg);
933 * \brief (DEPRECATED) Synchronize stream position with hardware
934 * \param pcm PCM handle
935 * \return 0 on success otherwise a negative error code
937 * Note this function does not update the actual r/w pointer
938 * for applications. The function #snd_pcm_avail_update()
939 * have to be called before any mmap begin+commit operation.
941 int snd_pcm_hwsync(snd_pcm_t *pcm)
943 assert(pcm);
944 if (CHECK_SANITY(! pcm->setup)) {
945 SNDMSG("PCM not set up");
946 return -EIO;
948 return pcm->fast_ops->hwsync(pcm->fast_op_arg);
950 #ifndef DOC_HIDDEN
951 link_warning(snd_pcm_hwsync, "Warning: snd_pcm_hwsync() is deprecated, consider to use snd_pcm_avail()");
952 #endif
955 * \brief Obtain delay for a running PCM handle
956 * \param pcm PCM handle
957 * \param delayp Returned delay in frames
958 * \return 0 on success otherwise a negative error code
960 * For playback the delay is defined as the time that a frame that is written
961 * to the PCM stream shortly after this call will take to be actually
962 * audible. It is as such the overall latency from the write call to the final
963 * DAC.
965 * For capture the delay is defined as the time that a frame that was
966 * digitized by the audio device takes until it can be read from the PCM
967 * stream shortly after this call returns. It is as such the overall latency
968 * from the initial ADC to the read call.
970 * Please note that hence in case of a playback underrun this value will not
971 * necessarily got down to 0.
973 * If the application is interested in the fill level of the playback buffer
974 * of the device, it should use #snd_pcm_avail*() functions. The
975 * value returned by that call is not directly related to the delay, since the
976 * latter might include some additional, fixed latencies the former does not.
978 * Note this function does not update the actual r/w pointer
979 * for applications. The function #snd_pcm_avail_update()
980 * have to be called before any begin+commit operation.
982 int snd_pcm_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp)
984 assert(pcm);
985 if (CHECK_SANITY(! pcm->setup)) {
986 SNDMSG("PCM not set up");
987 return -EIO;
989 return pcm->fast_ops->delay(pcm->fast_op_arg, delayp);
993 * \brief Resume from suspend, no samples are lost
994 * \param pcm PCM handle
995 * \return 0 on success otherwise a negative error code
996 * \retval -EAGAIN resume can't be proceed immediately (audio hardware is probably still suspended)
997 * \retval -ENOSYS hardware doesn't support this feature
999 * This function can be used when the stream is in the suspend state
1000 * to do the fine resume from this state. Not all hardware supports
1001 * this feature, when an -ENOSYS error is returned, use the \link ::snd_pcm_prepare() \endlink
1002 * function to recovery.
1004 int snd_pcm_resume(snd_pcm_t *pcm)
1006 assert(pcm);
1007 if (CHECK_SANITY(! pcm->setup)) {
1008 SNDMSG("PCM not set up");
1009 return -EIO;
1011 return pcm->fast_ops->resume(pcm->fast_op_arg);
1015 * \brief Obtain last position update hi-res timestamp
1016 * \param pcm PCM handle
1017 * \param avail Number of available frames when timestamp was grabbed
1018 * \param tstamp Hi-res timestamp
1019 * \return 0 on success otherwise a negative error code
1021 * Note this function does not update the actual r/w pointer
1022 * for applications.
1024 int snd_pcm_htimestamp(snd_pcm_t *pcm, snd_pcm_uframes_t *avail, snd_htimestamp_t *tstamp)
1026 assert(pcm);
1027 if (CHECK_SANITY(! pcm->setup)) {
1028 SNDMSG("PCM not set up");
1029 return -EIO;
1031 return pcm->fast_ops->htimestamp(pcm->fast_op_arg, avail, tstamp);
1035 * \brief Prepare PCM for use
1036 * \param pcm PCM handle
1037 * \return 0 on success otherwise a negative error code
1039 int snd_pcm_prepare(snd_pcm_t *pcm)
1041 assert(pcm);
1042 if (CHECK_SANITY(! pcm->setup)) {
1043 SNDMSG("PCM not set up");
1044 return -EIO;
1046 return pcm->fast_ops->prepare(pcm->fast_op_arg);
1050 * \brief Reset PCM position
1051 * \param pcm PCM handle
1052 * \return 0 on success otherwise a negative error code
1054 * Reduce PCM delay to 0.
1056 int snd_pcm_reset(snd_pcm_t *pcm)
1058 assert(pcm);
1059 if (CHECK_SANITY(! pcm->setup)) {
1060 SNDMSG("PCM not set up");
1061 return -EIO;
1063 return pcm->fast_ops->reset(pcm->fast_op_arg);
1067 * \brief Start a PCM
1068 * \param pcm PCM handle
1069 * \return 0 on success otherwise a negative error code
1071 int snd_pcm_start(snd_pcm_t *pcm)
1073 assert(pcm);
1074 if (CHECK_SANITY(! pcm->setup)) {
1075 SNDMSG("PCM not set up");
1076 return -EIO;
1078 return pcm->fast_ops->start(pcm->fast_op_arg);
1082 * \brief Stop a PCM dropping pending frames
1083 * \param pcm PCM handle
1084 * \return 0 on success otherwise a negative error code
1086 * This function stops the PCM <i>immediately</i>.
1087 * The pending samples on the buffer are ignored.
1089 * For processing all pending samples, use \link ::snd_pcm_drain() \endlink
1090 * instead.
1092 int snd_pcm_drop(snd_pcm_t *pcm)
1094 assert(pcm);
1095 if (CHECK_SANITY(! pcm->setup)) {
1096 SNDMSG("PCM not set up");
1097 return -EIO;
1099 return pcm->fast_ops->drop(pcm->fast_op_arg);
1103 * \brief Stop a PCM preserving pending frames
1104 * \param pcm PCM handle
1105 * \return 0 on success otherwise a negative error code
1106 * \retval -ESTRPIPE a suspend event occurred
1108 * For playback wait for all pending frames to be played and then stop
1109 * the PCM.
1110 * For capture stop PCM permitting to retrieve residual frames.
1112 * For stopping the PCM stream immediately, use \link ::snd_pcm_drop() \endlink
1113 * instead.
1115 int snd_pcm_drain(snd_pcm_t *pcm)
1117 assert(pcm);
1118 if (CHECK_SANITY(! pcm->setup)) {
1119 SNDMSG("PCM not set up");
1120 return -EIO;
1122 return pcm->fast_ops->drain(pcm->fast_op_arg);
1126 * \brief Pause/resume PCM
1127 * \param pcm PCM handle
1128 * \param enable 0 = resume, 1 = pause
1129 * \return 0 on success otherwise a negative error code
1131 * Note that this function works only on the hardware which supports
1132 * pause feature. You can check it via \link ::snd_pcm_hw_params_can_pause() \endlink
1133 * function.
1135 int snd_pcm_pause(snd_pcm_t *pcm, int enable)
1137 assert(pcm);
1138 if (CHECK_SANITY(! pcm->setup)) {
1139 SNDMSG("PCM not set up");
1140 return -EIO;
1142 return pcm->fast_ops->pause(pcm->fast_op_arg, enable);
1146 * \brief Get safe count of frames which can be rewinded
1147 * \param pcm PCM handle
1148 * \return a positive number of frames or negative error code
1150 * Note: The snd_pcm_rewind() can accept bigger value than returned
1151 * by this function. But it is not guaranteed that output stream
1152 * will be consistent with bigger value.
1154 snd_pcm_sframes_t snd_pcm_rewindable(snd_pcm_t *pcm)
1156 assert(pcm);
1157 if (CHECK_SANITY(! pcm->setup)) {
1158 SNDMSG("PCM not set up");
1159 return -EIO;
1161 return pcm->fast_ops->rewindable(pcm->fast_op_arg);
1165 * \brief Move application frame position backward
1166 * \param pcm PCM handle
1167 * \param frames wanted displacement in frames
1168 * \return a positive number for actual displacement otherwise a
1169 * negative error code
1171 snd_pcm_sframes_t snd_pcm_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
1173 assert(pcm);
1174 if (CHECK_SANITY(! pcm->setup)) {
1175 SNDMSG("PCM not set up");
1176 return -EIO;
1178 if (frames == 0)
1179 return 0;
1180 return pcm->fast_ops->rewind(pcm->fast_op_arg, frames);
1184 * \brief Get safe count of frames which can be forwarded
1185 * \param pcm PCM handle
1186 * \return a positive number of frames or negative error code
1188 * Note: The snd_pcm_forward() can accept bigger value than returned
1189 * by this function. But it is not guaranteed that output stream
1190 * will be consistent with bigger value.
1192 snd_pcm_sframes_t snd_pcm_forwardable(snd_pcm_t *pcm)
1194 assert(pcm);
1195 if (CHECK_SANITY(! pcm->setup)) {
1196 SNDMSG("PCM not set up");
1197 return -EIO;
1199 return pcm->fast_ops->forwardable(pcm->fast_op_arg);
1203 * \brief Move application frame position forward
1204 * \param pcm PCM handle
1205 * \param frames wanted skip in frames
1206 * \return a positive number for actual skip otherwise a negative error code
1207 * \retval 0 means no action
1209 #ifndef DOXYGEN
1210 snd_pcm_sframes_t INTERNAL(snd_pcm_forward)(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
1211 #else
1212 snd_pcm_sframes_t snd_pcm_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
1213 #endif
1215 assert(pcm);
1216 if (CHECK_SANITY(! pcm->setup)) {
1217 SNDMSG("PCM not set up");
1218 return -EIO;
1220 if (frames == 0)
1221 return 0;
1222 return pcm->fast_ops->forward(pcm->fast_op_arg, frames);
1224 use_default_symbol_version(__snd_pcm_forward, snd_pcm_forward, ALSA_0.9.0rc8);
1227 * \brief Write interleaved frames to a PCM
1228 * \param pcm PCM handle
1229 * \param buffer frames containing buffer
1230 * \param size frames to be written
1231 * \return a positive number of frames actually written otherwise a
1232 * negative error code
1233 * \retval -EBADFD PCM is not in the right state (#SND_PCM_STATE_PREPARED or #SND_PCM_STATE_RUNNING)
1234 * \retval -EPIPE an underrun occurred
1235 * \retval -ESTRPIPE a suspend event occurred (stream is suspended and waiting for an application recovery)
1237 * If the blocking behaviour is selected and it is running, then routine waits until
1238 * all requested frames are played or put to the playback ring buffer.
1239 * The returned number of frames can be less only if a signal or underrun occurred.
1241 * If the non-blocking behaviour is selected, then routine doesn't wait at all.
1243 snd_pcm_sframes_t snd_pcm_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size)
1245 assert(pcm);
1246 assert(size == 0 || buffer);
1247 if (CHECK_SANITY(! pcm->setup)) {
1248 SNDMSG("PCM not set up");
1249 return -EIO;
1251 if (pcm->access != SND_PCM_ACCESS_RW_INTERLEAVED) {
1252 SNDMSG("invalid access type %s", snd_pcm_access_name(pcm->access));
1253 return -EINVAL;
1255 return _snd_pcm_writei(pcm, buffer, size);
1259 * \brief Write non interleaved frames to a PCM
1260 * \param pcm PCM handle
1261 * \param bufs frames containing buffers (one for each channel)
1262 * \param size frames to be written
1263 * \return a positive number of frames actually written otherwise a
1264 * negative error code
1265 * \retval -EBADFD PCM is not in the right state (#SND_PCM_STATE_PREPARED or #SND_PCM_STATE_RUNNING)
1266 * \retval -EPIPE an underrun occurred
1267 * \retval -ESTRPIPE a suspend event occurred (stream is suspended and waiting for an application recovery)
1269 * If the blocking behaviour is selected and it is running, then routine waits until
1270 * all requested frames are played or put to the playback ring buffer.
1271 * The returned number of frames can be less only if a signal or underrun occurred.
1273 * If the non-blocking behaviour is selected, then routine doesn't wait at all.
1275 snd_pcm_sframes_t snd_pcm_writen(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size)
1277 assert(pcm);
1278 assert(size == 0 || bufs);
1279 if (CHECK_SANITY(! pcm->setup)) {
1280 SNDMSG("PCM not set up");
1281 return -EIO;
1283 if (pcm->access != SND_PCM_ACCESS_RW_NONINTERLEAVED) {
1284 SNDMSG("invalid access type %s", snd_pcm_access_name(pcm->access));
1285 return -EINVAL;
1287 return _snd_pcm_writen(pcm, bufs, size);
1291 * \brief Read interleaved frames from a PCM
1292 * \param pcm PCM handle
1293 * \param buffer frames containing buffer
1294 * \param size frames to be read
1295 * \return a positive number of frames actually read otherwise a
1296 * negative error code
1297 * \retval -EBADFD PCM is not in the right state (#SND_PCM_STATE_PREPARED or #SND_PCM_STATE_RUNNING)
1298 * \retval -EPIPE an overrun occurred
1299 * \retval -ESTRPIPE a suspend event occurred (stream is suspended and waiting for an application recovery)
1301 * If the blocking behaviour was selected and it is running, then routine waits until
1302 * all requested frames are filled. The returned number of frames can be less only
1303 * if a signal or underrun occurred.
1305 * If the non-blocking behaviour is selected, then routine doesn't wait at all.
1307 snd_pcm_sframes_t snd_pcm_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size)
1309 assert(pcm);
1310 assert(size == 0 || buffer);
1311 if (CHECK_SANITY(! pcm->setup)) {
1312 SNDMSG("PCM not set up");
1313 return -EIO;
1315 if (pcm->access != SND_PCM_ACCESS_RW_INTERLEAVED) {
1316 SNDMSG("invalid access type %s", snd_pcm_access_name(pcm->access));
1317 return -EINVAL;
1319 return _snd_pcm_readi(pcm, buffer, size);
1323 * \brief Read non interleaved frames to a PCM
1324 * \param pcm PCM handle
1325 * \param bufs frames containing buffers (one for each channel)
1326 * \param size frames to be read
1327 * \return a positive number of frames actually read otherwise a
1328 * negative error code
1329 * \retval -EBADFD PCM is not in the right state (#SND_PCM_STATE_PREPARED or #SND_PCM_STATE_RUNNING)
1330 * \retval -EPIPE an overrun occurred
1331 * \retval -ESTRPIPE a suspend event occurred (stream is suspended and waiting for an application recovery)
1333 * If the blocking behaviour was selected and it is running, then routine waits until
1334 * all requested frames are filled. The returned number of frames can be less only
1335 * if a signal or underrun occurred.
1337 * If the non-blocking behaviour is selected, then routine doesn't wait at all.
1339 snd_pcm_sframes_t snd_pcm_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size)
1341 assert(pcm);
1342 assert(size == 0 || bufs);
1343 if (CHECK_SANITY(! pcm->setup)) {
1344 SNDMSG("PCM not set up");
1345 return -EIO;
1347 if (pcm->access != SND_PCM_ACCESS_RW_NONINTERLEAVED) {
1348 SNDMSG("invalid access type %s", snd_pcm_access_name(pcm->access));
1349 return -EINVAL;
1351 return _snd_pcm_readn(pcm, bufs, size);
1355 * \brief Link two PCMs
1356 * \param pcm1 first PCM handle
1357 * \param pcm2 first PCM handle
1358 * \return 0 on success otherwise a negative error code
1360 * The two PCMs will start/stop/prepare in sync.
1362 int snd_pcm_link(snd_pcm_t *pcm1, snd_pcm_t *pcm2)
1364 assert(pcm1);
1365 assert(pcm2);
1366 if (pcm1->fast_ops->link)
1367 return pcm1->fast_ops->link(pcm1, pcm2);
1368 return -ENOSYS;
1372 * \brief Remove a PCM from a linked group
1373 * \param pcm PCM handle
1374 * \return 0 on success otherwise a negative error code
1376 int snd_pcm_unlink(snd_pcm_t *pcm)
1378 assert(pcm);
1379 if (pcm->fast_ops->unlink)
1380 return pcm->fast_ops->unlink(pcm);
1381 return -ENOSYS;
1385 * \brief get count of poll descriptors for PCM handle
1386 * \param pcm PCM handle
1387 * \return count of poll descriptors
1389 int snd_pcm_poll_descriptors_count(snd_pcm_t *pcm)
1391 assert(pcm);
1392 if (pcm->fast_ops->poll_descriptors_count)
1393 return pcm->fast_ops->poll_descriptors_count(pcm->fast_op_arg);
1394 return pcm->poll_fd_count;
1399 * \brief get poll descriptors
1400 * \param pcm PCM handle
1401 * \param pfds array of poll descriptors
1402 * \param space space in the poll descriptor array
1403 * \return count of filled descriptors
1405 * This function fills the given poll descriptor structs for the specified
1406 * PCM handle. The poll desctiptor array should have the size returned by
1407 * \link ::snd_pcm_poll_descriptors_count() \endlink function.
1409 * The result is intended for direct use with the poll() syscall.
1411 * For reading the returned events of poll descriptor after poll() system
1412 * call, use \link ::snd_pcm_poll_descriptors_revents() \endlink function.
1413 * The field values in pollfd structs may be bogus regarding the stream
1414 * direction from the application perspective (POLLIN might not imply read
1415 * direction and POLLOUT might not imply write), but
1416 * the \link ::snd_pcm_poll_descriptors_revents() \endlink function
1417 * does the right "demangling".
1419 * You can use output from this function as arguments for the select()
1420 * syscall, too. Do not forget to translate POLLIN and POLLOUT events to
1421 * corresponding FD_SET arrays and demangle events using
1422 * \link ::snd_pcm_poll_descriptors_revents() \endlink .
1424 int snd_pcm_poll_descriptors(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int space)
1426 assert(pcm && pfds);
1427 if (pcm->fast_ops->poll_descriptors)
1428 return pcm->fast_ops->poll_descriptors(pcm->fast_op_arg, pfds, space);
1429 if (pcm->poll_fd < 0) {
1430 SNDMSG("poll_fd < 0");
1431 return -EIO;
1433 if (space >= 1 && pfds) {
1434 pfds->fd = pcm->poll_fd;
1435 pfds->events = pcm->poll_events | POLLERR | POLLNVAL;
1436 } else {
1437 return 0;
1439 return 1;
1443 * \brief get returned events from poll descriptors
1444 * \param pcm PCM handle
1445 * \param pfds array of poll descriptors
1446 * \param nfds count of poll descriptors
1447 * \param revents pointer to the returned (single) event
1448 * \return zero if success, otherwise a negative error code
1450 * This function does "demangling" of the revents mask returned from
1451 * the poll() syscall to correct semantics (POLLIN = read, POLLOUT = write).
1453 * Note: The null event also exists. Even if poll() or select()
1454 * syscall returned that some events are waiting, this function might
1455 * return empty set of events. In this case, application should
1456 * do next event waiting using poll() or select().
1458 * Note: Even if multiple poll descriptors are used (i.e. pfds > 1),
1459 * this function returns only a single event.
1461 int snd_pcm_poll_descriptors_revents(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int nfds, unsigned short *revents)
1463 assert(pcm && pfds && revents);
1464 if (pcm->fast_ops->poll_revents)
1465 return pcm->fast_ops->poll_revents(pcm->fast_op_arg, pfds, nfds, revents);
1466 if (nfds == 1) {
1467 *revents = pfds->revents;
1468 return 0;
1470 return -EINVAL;
1473 #ifndef DOC_HIDDEN
1474 #define PCMTYPE(v) [SND_PCM_TYPE_##v] = #v
1475 #define STATE(v) [SND_PCM_STATE_##v] = #v
1476 #define STREAM(v) [SND_PCM_STREAM_##v] = #v
1477 #define READY(v) [SND_PCM_READY_##v] = #v
1478 #define XRUN(v) [SND_PCM_XRUN_##v] = #v
1479 #define SILENCE(v) [SND_PCM_SILENCE_##v] = #v
1480 #define TSTAMP(v) [SND_PCM_TSTAMP_##v] = #v
1481 #define ACCESS(v) [SND_PCM_ACCESS_##v] = #v
1482 #define START(v) [SND_PCM_START_##v] = #v
1483 #define HW_PARAM(v) [SND_PCM_HW_PARAM_##v] = #v
1484 #define SW_PARAM(v) [SND_PCM_SW_PARAM_##v] = #v
1485 #define FORMAT(v) [SND_PCM_FORMAT_##v] = #v
1486 #define SUBFORMAT(v) [SND_PCM_SUBFORMAT_##v] = #v
1488 #define FORMATD(v, d) [SND_PCM_FORMAT_##v] = d
1489 #define SUBFORMATD(v, d) [SND_PCM_SUBFORMAT_##v] = d
1492 static const char *const snd_pcm_stream_names[] = {
1493 STREAM(PLAYBACK),
1494 STREAM(CAPTURE),
1497 static const char *const snd_pcm_state_names[] = {
1498 STATE(OPEN),
1499 STATE(SETUP),
1500 STATE(PREPARED),
1501 STATE(RUNNING),
1502 STATE(XRUN),
1503 STATE(DRAINING),
1504 STATE(PAUSED),
1505 STATE(SUSPENDED),
1506 STATE(DISCONNECTED),
1509 static const char *const snd_pcm_access_names[] = {
1510 ACCESS(MMAP_INTERLEAVED),
1511 ACCESS(MMAP_NONINTERLEAVED),
1512 ACCESS(MMAP_COMPLEX),
1513 ACCESS(RW_INTERLEAVED),
1514 ACCESS(RW_NONINTERLEAVED),
1517 static const char *const snd_pcm_format_names[] = {
1518 FORMAT(S8),
1519 FORMAT(U8),
1520 FORMAT(S16_LE),
1521 FORMAT(S16_BE),
1522 FORMAT(U16_LE),
1523 FORMAT(U16_BE),
1524 FORMAT(S24_LE),
1525 FORMAT(S24_BE),
1526 FORMAT(U24_LE),
1527 FORMAT(U24_BE),
1528 FORMAT(S32_LE),
1529 FORMAT(S32_BE),
1530 FORMAT(U32_LE),
1531 FORMAT(U32_BE),
1532 FORMAT(FLOAT_LE),
1533 FORMAT(FLOAT_BE),
1534 FORMAT(FLOAT64_LE),
1535 FORMAT(FLOAT64_BE),
1536 FORMAT(IEC958_SUBFRAME_LE),
1537 FORMAT(IEC958_SUBFRAME_BE),
1538 FORMAT(MU_LAW),
1539 FORMAT(A_LAW),
1540 FORMAT(IMA_ADPCM),
1541 FORMAT(MPEG),
1542 FORMAT(GSM),
1543 FORMAT(SPECIAL),
1544 FORMAT(S24_3LE),
1545 FORMAT(S24_3BE),
1546 FORMAT(U24_3LE),
1547 FORMAT(U24_3BE),
1548 FORMAT(S20_3LE),
1549 FORMAT(S20_3BE),
1550 FORMAT(U20_3LE),
1551 FORMAT(U20_3BE),
1552 FORMAT(S18_3LE),
1553 FORMAT(S18_3BE),
1554 FORMAT(U18_3LE),
1555 FORMAT(U18_3BE),
1558 static const char *const snd_pcm_format_aliases[SND_PCM_FORMAT_LAST+1] = {
1559 FORMAT(S16),
1560 FORMAT(U16),
1561 FORMAT(S24),
1562 FORMAT(U24),
1563 FORMAT(S32),
1564 FORMAT(U32),
1565 FORMAT(FLOAT),
1566 FORMAT(FLOAT64),
1567 FORMAT(IEC958_SUBFRAME),
1570 static const char *const snd_pcm_format_descriptions[] = {
1571 FORMATD(S8, "Signed 8 bit"),
1572 FORMATD(U8, "Unsigned 8 bit"),
1573 FORMATD(S16_LE, "Signed 16 bit Little Endian"),
1574 FORMATD(S16_BE, "Signed 16 bit Big Endian"),
1575 FORMATD(U16_LE, "Unsigned 16 bit Little Endian"),
1576 FORMATD(U16_BE, "Unsigned 16 bit Big Endian"),
1577 FORMATD(S24_LE, "Signed 24 bit Little Endian"),
1578 FORMATD(S24_BE, "Signed 24 bit Big Endian"),
1579 FORMATD(U24_LE, "Unsigned 24 bit Little Endian"),
1580 FORMATD(U24_BE, "Unsigned 24 bit Big Endian"),
1581 FORMATD(S32_LE, "Signed 32 bit Little Endian"),
1582 FORMATD(S32_BE, "Signed 32 bit Big Endian"),
1583 FORMATD(U32_LE, "Unsigned 32 bit Little Endian"),
1584 FORMATD(U32_BE, "Unsigned 32 bit Big Endian"),
1585 FORMATD(FLOAT_LE, "Float 32 bit Little Endian"),
1586 FORMATD(FLOAT_BE, "Float 32 bit Big Endian"),
1587 FORMATD(FLOAT64_LE, "Float 64 bit Little Endian"),
1588 FORMATD(FLOAT64_BE, "Float 64 bit Big Endian"),
1589 FORMATD(IEC958_SUBFRAME_LE, "IEC-958 Little Endian"),
1590 FORMATD(IEC958_SUBFRAME_BE, "IEC-958 Big Endian"),
1591 FORMATD(MU_LAW, "Mu-Law"),
1592 FORMATD(A_LAW, "A-Law"),
1593 FORMATD(IMA_ADPCM, "Ima-ADPCM"),
1594 FORMATD(MPEG, "MPEG"),
1595 FORMATD(GSM, "GSM"),
1596 FORMATD(SPECIAL, "Special"),
1597 FORMATD(S24_3LE, "Signed 24 bit Little Endian in 3bytes"),
1598 FORMATD(S24_3BE, "Signed 24 bit Big Endian in 3bytes"),
1599 FORMATD(U24_3LE, "Unsigned 24 bit Little Endian in 3bytes"),
1600 FORMATD(U24_3BE, "Unsigned 24 bit Big Endian in 3bytes"),
1601 FORMATD(S20_3LE, "Signed 20 bit Little Endian in 3bytes"),
1602 FORMATD(S20_3BE, "Signed 20 bit Big Endian in 3bytes"),
1603 FORMATD(U20_3LE, "Unsigned 20 bit Little Endian in 3bytes"),
1604 FORMATD(U20_3BE, "Unsigned 20 bit Big Endian in 3bytes"),
1605 FORMATD(S18_3LE, "Signed 18 bit Little Endian in 3bytes"),
1606 FORMATD(S18_3BE, "Signed 18 bit Big Endian in 3bytes"),
1607 FORMATD(U18_3LE, "Unsigned 18 bit Little Endian in 3bytes"),
1608 FORMATD(U18_3BE, "Unsigned 18 bit Big Endian in 3bytes"),
1611 static const char *const snd_pcm_type_names[] = {
1612 PCMTYPE(HW),
1613 PCMTYPE(HOOKS),
1614 PCMTYPE(MULTI),
1615 PCMTYPE(FILE),
1616 PCMTYPE(NULL),
1617 PCMTYPE(SHM),
1618 PCMTYPE(INET),
1619 PCMTYPE(COPY),
1620 PCMTYPE(LINEAR),
1621 PCMTYPE(ALAW),
1622 PCMTYPE(MULAW),
1623 PCMTYPE(ADPCM),
1624 PCMTYPE(RATE),
1625 PCMTYPE(ROUTE),
1626 PCMTYPE(PLUG),
1627 PCMTYPE(SHARE),
1628 PCMTYPE(METER),
1629 PCMTYPE(MIX),
1630 PCMTYPE(DROUTE),
1631 PCMTYPE(LBSERVER),
1632 PCMTYPE(LINEAR_FLOAT),
1633 PCMTYPE(LADSPA),
1634 PCMTYPE(DMIX),
1635 PCMTYPE(JACK),
1636 PCMTYPE(DSNOOP),
1637 PCMTYPE(IEC958),
1638 PCMTYPE(SOFTVOL),
1639 PCMTYPE(IOPLUG),
1640 PCMTYPE(EXTPLUG),
1641 PCMTYPE(MMAP_EMUL),
1644 static const char *const snd_pcm_subformat_names[] = {
1645 SUBFORMAT(STD),
1648 static const char *const snd_pcm_subformat_descriptions[] = {
1649 SUBFORMATD(STD, "Standard"),
1652 static const char *const snd_pcm_start_mode_names[] = {
1653 START(EXPLICIT),
1654 START(DATA),
1657 static const char *const snd_pcm_xrun_mode_names[] = {
1658 XRUN(NONE),
1659 XRUN(STOP),
1662 static const char *const snd_pcm_tstamp_mode_names[] = {
1663 TSTAMP(NONE),
1664 TSTAMP(ENABLE),
1666 #endif
1669 * \brief get name of PCM stream type
1670 * \param stream PCM stream type
1671 * \return ascii name of PCM stream type
1673 const char *snd_pcm_stream_name(snd_pcm_stream_t stream)
1675 if (stream > SND_PCM_STREAM_LAST)
1676 return NULL;
1677 return snd_pcm_stream_names[stream];
1681 * \brief get name of PCM access type
1682 * \param acc PCM access type
1683 * \return ascii name of PCM access type
1685 const char *snd_pcm_access_name(snd_pcm_access_t acc)
1687 if (acc > SND_PCM_ACCESS_LAST)
1688 return NULL;
1689 return snd_pcm_access_names[acc];
1693 * \brief get name of PCM sample format
1694 * \param format PCM sample format
1695 * \return ascii name of PCM sample format
1697 const char *snd_pcm_format_name(snd_pcm_format_t format)
1699 if (format > SND_PCM_FORMAT_LAST)
1700 return NULL;
1701 return snd_pcm_format_names[format];
1705 * \brief get description of PCM sample format
1706 * \param format PCM sample format
1707 * \return ascii description of PCM sample format
1709 const char *snd_pcm_format_description(snd_pcm_format_t format)
1711 if (format > SND_PCM_FORMAT_LAST)
1712 return NULL;
1713 return snd_pcm_format_descriptions[format];
1717 * \brief get PCM sample format from name
1718 * \param name PCM sample format name (case insensitive)
1719 * \return PCM sample format
1721 snd_pcm_format_t snd_pcm_format_value(const char* name)
1723 snd_pcm_format_t format;
1724 for (format = 0; format <= SND_PCM_FORMAT_LAST; format++) {
1725 if (snd_pcm_format_names[format] &&
1726 strcasecmp(name, snd_pcm_format_names[format]) == 0) {
1727 return format;
1729 if (snd_pcm_format_aliases[format] &&
1730 strcasecmp(name, snd_pcm_format_aliases[format]) == 0) {
1731 return format;
1734 for (format = 0; format <= SND_PCM_FORMAT_LAST; format++) {
1735 if (snd_pcm_format_descriptions[format] &&
1736 strcasecmp(name, snd_pcm_format_descriptions[format]) == 0) {
1737 return format;
1740 return SND_PCM_FORMAT_UNKNOWN;
1744 * \brief get name of PCM sample subformat
1745 * \param subformat PCM sample subformat
1746 * \return ascii name of PCM sample subformat
1748 const char *snd_pcm_subformat_name(snd_pcm_subformat_t subformat)
1750 if (subformat > SND_PCM_SUBFORMAT_LAST)
1751 return NULL;
1752 return snd_pcm_subformat_names[subformat];
1756 * \brief get description of PCM sample subformat
1757 * \param subformat PCM sample subformat
1758 * \return ascii description of PCM sample subformat
1760 const char *snd_pcm_subformat_description(snd_pcm_subformat_t subformat)
1762 if (subformat > SND_PCM_SUBFORMAT_LAST)
1763 return NULL;
1764 return snd_pcm_subformat_descriptions[subformat];
1768 * \brief (DEPRECATED) get name of PCM start mode setting
1769 * \param mode PCM start mode
1770 * \return ascii name of PCM start mode setting
1772 const char *snd_pcm_start_mode_name(snd_pcm_start_t mode)
1774 if (mode > SND_PCM_START_LAST)
1775 return NULL;
1776 return snd_pcm_start_mode_names[mode];
1779 #ifndef DOC_HIDDEN
1780 link_warning(snd_pcm_start_mode_name, "Warning: start_mode is deprecated, consider to use start_threshold");
1781 #endif
1784 * \brief (DEPRECATED) get name of PCM xrun mode setting
1785 * \param mode PCM xrun mode
1786 * \return ascii name of PCM xrun mode setting
1788 const char *snd_pcm_xrun_mode_name(snd_pcm_xrun_t mode)
1790 if (mode > SND_PCM_XRUN_LAST)
1791 return NULL;
1792 return snd_pcm_xrun_mode_names[mode];
1795 #ifndef DOC_HIDDEN
1796 link_warning(snd_pcm_xrun_mode_name, "Warning: xrun_mode is deprecated, consider to use stop_threshold");
1797 #endif
1800 * \brief get name of PCM tstamp mode setting
1801 * \param mode PCM tstamp mode
1802 * \return ascii name of PCM tstamp mode setting
1804 const char *snd_pcm_tstamp_mode_name(snd_pcm_tstamp_t mode)
1806 if (mode > SND_PCM_TSTAMP_LAST)
1807 return NULL;
1808 return snd_pcm_tstamp_mode_names[mode];
1812 * \brief get name of PCM state
1813 * \param state PCM state
1814 * \return ascii name of PCM state
1816 const char *snd_pcm_state_name(snd_pcm_state_t state)
1818 if (state > SND_PCM_STATE_LAST)
1819 return NULL;
1820 return snd_pcm_state_names[state];
1824 * \brief get name of PCM type
1825 * \param type PCM type
1826 * \return ascii name of PCM type
1828 #ifndef DOXYGEN
1829 const char *INTERNAL(snd_pcm_type_name)(snd_pcm_type_t type)
1830 #else
1831 const char *snd_pcm_type_name(snd_pcm_type_t type)
1832 #endif
1834 if (type > SND_PCM_TYPE_LAST)
1835 return NULL;
1836 return snd_pcm_type_names[type];
1838 use_default_symbol_version(__snd_pcm_type_name, snd_pcm_type_name, ALSA_0.9.0);
1841 * \brief Dump current hardware setup for PCM
1842 * \param pcm PCM handle
1843 * \param out Output handle
1844 * \return 0 on success otherwise a negative error code
1846 int snd_pcm_dump_hw_setup(snd_pcm_t *pcm, snd_output_t *out)
1848 assert(pcm);
1849 assert(out);
1850 if (CHECK_SANITY(! pcm->setup)) {
1851 SNDMSG("PCM not set up");
1852 return -EIO;
1854 snd_output_printf(out, " stream : %s\n", snd_pcm_stream_name(pcm->stream));
1855 snd_output_printf(out, " access : %s\n", snd_pcm_access_name(pcm->access));
1856 snd_output_printf(out, " format : %s\n", snd_pcm_format_name(pcm->format));
1857 snd_output_printf(out, " subformat : %s\n", snd_pcm_subformat_name(pcm->subformat));
1858 snd_output_printf(out, " channels : %u\n", pcm->channels);
1859 snd_output_printf(out, " rate : %u\n", pcm->rate);
1860 snd_output_printf(out, " exact rate : %g (%u/%u)\n",
1861 (pcm->rate_den ? ((double) pcm->rate_num / pcm->rate_den) : 0.0),
1862 pcm->rate_num, pcm->rate_den);
1863 snd_output_printf(out, " msbits : %u\n", pcm->msbits);
1864 snd_output_printf(out, " buffer_size : %lu\n", pcm->buffer_size);
1865 snd_output_printf(out, " period_size : %lu\n", pcm->period_size);
1866 snd_output_printf(out, " period_time : %u\n", pcm->period_time);
1867 return 0;
1871 * \brief Dump current software setup for PCM
1872 * \param pcm PCM handle
1873 * \param out Output handle
1874 * \return 0 on success otherwise a negative error code
1876 int snd_pcm_dump_sw_setup(snd_pcm_t *pcm, snd_output_t *out)
1878 assert(pcm);
1879 assert(out);
1880 if (CHECK_SANITY(! pcm->setup)) {
1881 SNDMSG("PCM not set up");
1882 return -EIO;
1884 snd_output_printf(out, " tstamp_mode : %s\n", snd_pcm_tstamp_mode_name(pcm->tstamp_mode));
1885 snd_output_printf(out, " period_step : %d\n", pcm->period_step);
1886 snd_output_printf(out, " avail_min : %ld\n", pcm->avail_min);
1887 snd_output_printf(out, " period_event : %i\n", pcm->period_event);
1888 snd_output_printf(out, " start_threshold : %ld\n", pcm->start_threshold);
1889 snd_output_printf(out, " stop_threshold : %ld\n", pcm->stop_threshold);
1890 snd_output_printf(out, " silence_threshold: %ld\n", pcm->silence_threshold);
1891 snd_output_printf(out, " silence_size : %ld\n", pcm->silence_size);
1892 snd_output_printf(out, " boundary : %ld\n", pcm->boundary);
1893 return 0;
1897 * \brief Dump current setup (hardware and software) for PCM
1898 * \param pcm PCM handle
1899 * \param out Output handle
1900 * \return 0 on success otherwise a negative error code
1902 int snd_pcm_dump_setup(snd_pcm_t *pcm, snd_output_t *out)
1904 snd_pcm_dump_hw_setup(pcm, out);
1905 snd_pcm_dump_sw_setup(pcm, out);
1906 return 0;
1910 * \brief Dump status
1911 * \param status Status container
1912 * \param out Output handle
1913 * \return 0 on success otherwise a negative error code
1915 int snd_pcm_status_dump(snd_pcm_status_t *status, snd_output_t *out)
1917 assert(status);
1918 snd_output_printf(out, " state : %s\n", snd_pcm_state_name((snd_pcm_state_t) status->state));
1919 snd_output_printf(out, " trigger_time: %ld.%06ld\n",
1920 status->trigger_tstamp.tv_sec, status->trigger_tstamp.tv_nsec);
1921 snd_output_printf(out, " tstamp : %ld.%06ld\n",
1922 status->tstamp.tv_sec, status->tstamp.tv_nsec);
1923 snd_output_printf(out, " delay : %ld\n", (long)status->delay);
1924 snd_output_printf(out, " avail : %ld\n", (long)status->avail);
1925 snd_output_printf(out, " avail_max : %ld\n", (long)status->avail_max);
1926 return 0;
1930 * \brief Dump PCM info
1931 * \param pcm PCM handle
1932 * \param out Output handle
1933 * \return 0 on success otherwise a negative error code
1935 int snd_pcm_dump(snd_pcm_t *pcm, snd_output_t *out)
1937 assert(pcm);
1938 assert(out);
1939 pcm->ops->dump(pcm->op_arg, out);
1940 return 0;
1944 * \brief Convert bytes in frames for a PCM
1945 * \param pcm PCM handle
1946 * \param bytes quantity in bytes
1947 * \return quantity expressed in frames
1949 snd_pcm_sframes_t snd_pcm_bytes_to_frames(snd_pcm_t *pcm, ssize_t bytes)
1951 assert(pcm);
1952 if (CHECK_SANITY(! pcm->setup)) {
1953 SNDMSG("PCM not set up");
1954 return -EIO;
1956 return bytes * 8 / pcm->frame_bits;
1960 * \brief Convert frames in bytes for a PCM
1961 * \param pcm PCM handle
1962 * \param frames quantity in frames
1963 * \return quantity expressed in bytes
1965 ssize_t snd_pcm_frames_to_bytes(snd_pcm_t *pcm, snd_pcm_sframes_t frames)
1967 assert(pcm);
1968 if (CHECK_SANITY(! pcm->setup)) {
1969 SNDMSG("PCM not set up");
1970 return -EIO;
1972 return frames * pcm->frame_bits / 8;
1976 * \brief Convert bytes in samples for a PCM
1977 * \param pcm PCM handle
1978 * \param bytes quantity in bytes
1979 * \return quantity expressed in samples
1981 long snd_pcm_bytes_to_samples(snd_pcm_t *pcm, ssize_t bytes)
1983 assert(pcm);
1984 if (CHECK_SANITY(! pcm->setup)) {
1985 SNDMSG("PCM not set up");
1986 return -EIO;
1988 return bytes * 8 / pcm->sample_bits;
1992 * \brief Convert samples in bytes for a PCM
1993 * \param pcm PCM handle
1994 * \param samples quantity in samples
1995 * \return quantity expressed in bytes
1997 ssize_t snd_pcm_samples_to_bytes(snd_pcm_t *pcm, long samples)
1999 assert(pcm);
2000 if (CHECK_SANITY(! pcm->setup)) {
2001 SNDMSG("PCM not set up");
2002 return -EIO;
2004 return samples * pcm->sample_bits / 8;
2008 * \brief Add an async handler for a PCM
2009 * \param handler Returned handler handle
2010 * \param pcm PCM handle
2011 * \param callback Callback function
2012 * \param private_data Callback private data
2013 * \return 0 otherwise a negative error code on failure
2015 * The asynchronous callback is called when period boundary elapses.
2017 int snd_async_add_pcm_handler(snd_async_handler_t **handler, snd_pcm_t *pcm,
2018 snd_async_callback_t callback, void *private_data)
2020 int err;
2021 int was_empty;
2022 snd_async_handler_t *h;
2023 err = snd_async_add_handler(&h, _snd_pcm_async_descriptor(pcm),
2024 callback, private_data);
2025 if (err < 0)
2026 return err;
2027 h->type = SND_ASYNC_HANDLER_PCM;
2028 h->u.pcm = pcm;
2029 was_empty = list_empty(&pcm->async_handlers);
2030 list_add_tail(&h->hlist, &pcm->async_handlers);
2031 if (was_empty) {
2032 err = snd_pcm_async(pcm, snd_async_handler_get_signo(h), getpid());
2033 if (err < 0) {
2034 snd_async_del_handler(h);
2035 return err;
2038 *handler = h;
2039 return 0;
2043 * \brief Return PCM handle related to an async handler
2044 * \param handler Async handler handle
2045 * \return PCM handle
2047 snd_pcm_t *snd_async_handler_get_pcm(snd_async_handler_t *handler)
2049 if (handler->type != SND_ASYNC_HANDLER_PCM) {
2050 SNDMSG("invalid handler type %d", handler->type);
2051 return NULL;
2053 return handler->u.pcm;
2056 static const char *const build_in_pcms[] = {
2057 "adpcm", "alaw", "copy", "dmix", "file", "hooks", "hw", "ladspa", "lfloat",
2058 "linear", "meter", "mulaw", "multi", "null", "empty", "plug", "rate", "route", "share",
2059 "shm", "dsnoop", "dshare", "asym", "iec958", "softvol", "mmap_emul",
2060 NULL
2063 static int snd_pcm_open_conf(snd_pcm_t **pcmp, const char *name,
2064 snd_config_t *pcm_root, snd_config_t *pcm_conf,
2065 snd_pcm_stream_t stream, int mode)
2067 const char *str;
2068 char *buf = NULL, *buf1 = NULL;
2069 int err;
2070 snd_config_t *conf, *type_conf = NULL, *tmp;
2071 snd_config_iterator_t i, next;
2072 const char *id;
2073 const char *lib = NULL, *open_name = NULL;
2074 int (*open_func)(snd_pcm_t **, const char *,
2075 snd_config_t *, snd_config_t *,
2076 snd_pcm_stream_t, int) = NULL;
2077 #ifndef PIC
2078 extern void *snd_pcm_open_symbols(void);
2079 #endif
2080 if (snd_config_get_type(pcm_conf) != SND_CONFIG_TYPE_COMPOUND) {
2081 char *val;
2082 id = NULL;
2083 snd_config_get_id(pcm_conf, &id);
2084 val = NULL;
2085 snd_config_get_ascii(pcm_conf, &val);
2086 SNDERR("Invalid type for PCM %s%sdefinition (id: %s, value: %s)", name ? name : "", name ? " " : "", id, val);
2087 free(val);
2088 return -EINVAL;
2090 err = snd_config_search(pcm_conf, "type", &conf);
2091 if (err < 0) {
2092 SNDERR("type is not defined");
2093 return err;
2095 err = snd_config_get_id(conf, &id);
2096 if (err < 0) {
2097 SNDERR("unable to get id");
2098 return err;
2100 err = snd_config_get_string(conf, &str);
2101 if (err < 0) {
2102 SNDERR("Invalid type for %s", id);
2103 return err;
2105 err = snd_config_search_definition(pcm_root, "pcm_type", str, &type_conf);
2106 if (err >= 0) {
2107 if (snd_config_get_type(type_conf) != SND_CONFIG_TYPE_COMPOUND) {
2108 SNDERR("Invalid type for PCM type %s definition", str);
2109 goto _err;
2111 snd_config_for_each(i, next, type_conf) {
2112 snd_config_t *n = snd_config_iterator_entry(i);
2113 const char *id;
2114 if (snd_config_get_id(n, &id) < 0)
2115 continue;
2116 if (strcmp(id, "comment") == 0)
2117 continue;
2118 if (strcmp(id, "lib") == 0) {
2119 err = snd_config_get_string(n, &lib);
2120 if (err < 0) {
2121 SNDERR("Invalid type for %s", id);
2122 goto _err;
2124 continue;
2126 if (strcmp(id, "open") == 0) {
2127 err = snd_config_get_string(n, &open_name);
2128 if (err < 0) {
2129 SNDERR("Invalid type for %s", id);
2130 goto _err;
2132 continue;
2134 SNDERR("Unknown field %s", id);
2135 err = -EINVAL;
2136 goto _err;
2139 if (!open_name) {
2140 buf = malloc(strlen(str) + 32);
2141 if (buf == NULL) {
2142 err = -ENOMEM;
2143 goto _err;
2145 open_name = buf;
2146 sprintf(buf, "_snd_pcm_%s_open", str);
2148 if (!lib) {
2149 const char *const *build_in = build_in_pcms;
2150 while (*build_in) {
2151 if (!strcmp(*build_in, str))
2152 break;
2153 build_in++;
2155 if (*build_in == NULL) {
2156 buf1 = malloc(strlen(str) + sizeof(ALSA_PLUGIN_DIR) + 32);
2157 if (buf1 == NULL) {
2158 err = -ENOMEM;
2159 goto _err;
2161 lib = buf1;
2162 sprintf(buf1, "%s/libasound_module_pcm_%s.so", ALSA_PLUGIN_DIR, str);
2165 #ifndef PIC
2166 snd_pcm_open_symbols(); /* this call is for static linking only */
2167 #endif
2168 open_func = snd_dlobj_cache_get(lib, open_name,
2169 SND_DLSYM_VERSION(SND_PCM_DLSYM_VERSION), 1);
2170 if (open_func) {
2171 err = open_func(pcmp, name, pcm_root, pcm_conf, stream, mode);
2172 if (err >= 0) {
2173 (*pcmp)->open_func = open_func;
2174 err = 0;
2175 } else {
2176 snd_dlobj_cache_put(open_func);
2178 } else {
2179 err = -ENXIO;
2181 if (err >= 0) {
2182 err = snd_config_search(pcm_root, "defaults.pcm.compat", &tmp);
2183 if (err >= 0) {
2184 long i;
2185 if (snd_config_get_integer(tmp, &i) >= 0) {
2186 if (i > 0)
2187 (*pcmp)->compat = 1;
2189 } else {
2190 char *str = getenv("LIBASOUND_COMPAT");
2191 if (str && *str)
2192 (*pcmp)->compat = 1;
2194 err = snd_config_search(pcm_root, "defaults.pcm.minperiodtime", &tmp);
2195 if (err >= 0)
2196 snd_config_get_integer(tmp, &(*pcmp)->minperiodtime);
2197 err = 0;
2199 _err:
2200 if (type_conf)
2201 snd_config_delete(type_conf);
2202 free(buf);
2203 free(buf1);
2204 return err;
2207 static int snd_pcm_open_noupdate(snd_pcm_t **pcmp, snd_config_t *root,
2208 const char *name, snd_pcm_stream_t stream,
2209 int mode, int hop)
2211 int err;
2212 snd_config_t *pcm_conf;
2213 const char *str;
2215 err = snd_config_search_definition(root, "pcm", name, &pcm_conf);
2216 if (err < 0) {
2217 SNDERR("Unknown PCM %s", name);
2218 return err;
2220 if (snd_config_get_string(pcm_conf, &str) >= 0)
2221 err = snd_pcm_open_noupdate(pcmp, root, str, stream, mode,
2222 hop + 1);
2223 else {
2224 snd_config_set_hop(pcm_conf, hop);
2225 err = snd_pcm_open_conf(pcmp, name, root, pcm_conf, stream, mode);
2227 snd_config_delete(pcm_conf);
2228 return err;
2232 * \brief Opens a PCM
2233 * \param pcmp Returned PCM handle
2234 * \param name ASCII identifier of the PCM handle
2235 * \param stream Wanted stream
2236 * \param mode Open mode (see #SND_PCM_NONBLOCK, #SND_PCM_ASYNC)
2237 * \return 0 on success otherwise a negative error code
2239 int snd_pcm_open(snd_pcm_t **pcmp, const char *name,
2240 snd_pcm_stream_t stream, int mode)
2242 int err;
2243 assert(pcmp && name);
2244 err = snd_config_update();
2245 if (err < 0)
2246 return err;
2247 return snd_pcm_open_noupdate(pcmp, snd_config, name, stream, mode, 0);
2251 * \brief Opens a PCM using local configuration
2252 * \param pcmp Returned PCM handle
2253 * \param name ASCII identifier of the PCM handle
2254 * \param stream Wanted stream
2255 * \param mode Open mode (see #SND_PCM_NONBLOCK, #SND_PCM_ASYNC)
2256 * \param lconf Local configuration
2257 * \return 0 on success otherwise a negative error code
2259 int snd_pcm_open_lconf(snd_pcm_t **pcmp, const char *name,
2260 snd_pcm_stream_t stream, int mode,
2261 snd_config_t *lconf)
2263 assert(pcmp && name && lconf);
2264 return snd_pcm_open_noupdate(pcmp, lconf, name, stream, mode, 0);
2268 * \brief Opens a fallback PCM
2269 * \param pcmp Returned PCM handle
2270 * \param root Configuration root
2271 * \param name ASCII identifier of the PCM handle
2272 * \param orig_name The original ASCII name
2273 * \param stream Wanted stream
2274 * \param mode Open mode (see #SND_PCM_NONBLOCK, #SND_PCM_ASYNC)
2275 * \return 0 on success otherwise a negative error code
2277 int snd_pcm_open_fallback(snd_pcm_t **pcmp, snd_config_t *root,
2278 const char *name, const char *orig_name,
2279 snd_pcm_stream_t stream, int mode)
2281 int err;
2282 assert(pcmp && name && root);
2283 err = snd_pcm_open_noupdate(pcmp, root, name, stream, mode, 0);
2284 if (err >= 0) {
2285 free((*pcmp)->name);
2286 (*pcmp)->name = orig_name ? strdup(orig_name) : NULL;
2288 return err;
2291 #ifndef DOC_HIDDEN
2292 int snd_pcm_new(snd_pcm_t **pcmp, snd_pcm_type_t type, const char *name,
2293 snd_pcm_stream_t stream, int mode)
2295 snd_pcm_t *pcm;
2296 pcm = calloc(1, sizeof(*pcm));
2297 if (!pcm)
2298 return -ENOMEM;
2299 pcm->type = type;
2300 if (name)
2301 pcm->name = strdup(name);
2302 pcm->stream = stream;
2303 pcm->mode = mode;
2304 pcm->poll_fd_count = 1;
2305 pcm->poll_fd = -1;
2306 pcm->op_arg = pcm;
2307 pcm->fast_op_arg = pcm;
2308 INIT_LIST_HEAD(&pcm->async_handlers);
2309 *pcmp = pcm;
2310 return 0;
2313 int snd_pcm_free(snd_pcm_t *pcm)
2315 assert(pcm);
2316 free(pcm->name);
2317 free(pcm->hw.link_dst);
2318 free(pcm->appl.link_dst);
2319 snd_dlobj_cache_put(pcm->open_func);
2320 free(pcm);
2321 return 0;
2324 int snd_pcm_open_named_slave(snd_pcm_t **pcmp, const char *name,
2325 snd_config_t *root,
2326 snd_config_t *conf, snd_pcm_stream_t stream,
2327 int mode, snd_config_t *parent_conf)
2329 const char *str;
2330 int hop;
2332 if ((hop = snd_config_check_hop(parent_conf)) < 0)
2333 return hop;
2334 if (snd_config_get_string(conf, &str) >= 0)
2335 return snd_pcm_open_noupdate(pcmp, root, str, stream, mode,
2336 hop + 1);
2337 return snd_pcm_open_conf(pcmp, name, root, conf, stream, mode);
2339 #endif
2342 * \brief Wait for a PCM to become ready
2343 * \param pcm PCM handle
2344 * \param timeout maximum time in milliseconds to wait,
2345 * a negative value means infinity
2346 * \return a positive value on success otherwise a negative error code
2347 * (-EPIPE for the xrun and -ESTRPIPE for the suspended status,
2348 * others for general errors)
2349 * \retval 0 timeout occurred
2350 * \retval 1 PCM stream is ready for I/O
2352 int snd_pcm_wait(snd_pcm_t *pcm, int timeout)
2354 if (snd_pcm_mmap_avail(pcm) >= pcm->avail_min) {
2355 /* check more precisely */
2356 switch (snd_pcm_state(pcm)) {
2357 case SND_PCM_STATE_XRUN:
2358 return -EPIPE;
2359 case SND_PCM_STATE_SUSPENDED:
2360 return -ESTRPIPE;
2361 case SND_PCM_STATE_DISCONNECTED:
2362 return -ENODEV;
2363 default:
2364 return 1;
2367 return snd_pcm_wait_nocheck(pcm, timeout);
2370 #ifndef DOC_HIDDEN
2372 * like snd_pcm_wait() but doesn't check mmap_avail before calling poll()
2374 * used in drain code in some plugins
2376 int snd_pcm_wait_nocheck(snd_pcm_t *pcm, int timeout)
2378 struct pollfd *pfd;
2379 unsigned short revents = 0;
2380 int npfds, err, err_poll;
2382 npfds = snd_pcm_poll_descriptors_count(pcm);
2383 if (npfds <= 0 || npfds >= 16) {
2384 SNDERR("Invalid poll_fds %d\n", npfds);
2385 return -EIO;
2387 pfd = alloca(sizeof(*pfd) * npfds);
2388 err = snd_pcm_poll_descriptors(pcm, pfd, npfds);
2389 if (err < 0)
2390 return err;
2391 if (err != npfds) {
2392 SNDMSG("invalid poll descriptors %d\n", err);
2393 return -EIO;
2395 do {
2396 err_poll = poll(pfd, npfds, timeout);
2397 if (err_poll < 0) {
2398 if (errno == EINTR)
2399 continue;
2400 return -errno;
2402 if (! err_poll)
2403 break;
2404 err = snd_pcm_poll_descriptors_revents(pcm, pfd, npfds, &revents);
2405 if (err < 0)
2406 return err;
2407 if (revents & (POLLERR | POLLNVAL)) {
2408 /* check more precisely */
2409 switch (snd_pcm_state(pcm)) {
2410 case SND_PCM_STATE_XRUN:
2411 return -EPIPE;
2412 case SND_PCM_STATE_SUSPENDED:
2413 return -ESTRPIPE;
2414 case SND_PCM_STATE_DISCONNECTED:
2415 return -ENODEV;
2416 default:
2417 return -EIO;
2420 } while (!(revents & (POLLIN | POLLOUT)));
2421 #if 0 /* very useful code to test poll related problems */
2423 snd_pcm_sframes_t avail_update;
2424 snd_pcm_hwsync(pcm);
2425 avail_update = snd_pcm_avail_update(pcm);
2426 if (avail_update < (snd_pcm_sframes_t)pcm->avail_min) {
2427 printf("*** snd_pcm_wait() FATAL ERROR!!!\n");
2428 printf("avail_min = %li, avail_update = %li\n", pcm->avail_min, avail_update);
2431 #endif
2432 return err_poll > 0 ? 1 : 0;
2434 #endif
2437 * \brief Return number of frames ready to be read (capture) / written (playback)
2438 * \param pcm PCM handle
2439 * \return a positive number of frames ready otherwise a negative
2440 * error code
2442 * On capture does all the actions needed to transport to application
2443 * level all the ready frames across underlying layers.
2445 * The position is not synced with hardware (driver) position in the sound
2446 * ring buffer in this function. This function is a light version of
2447 * #snd_pcm_avail() .
2449 * Using this function is ideal after poll() or select() when audio
2450 * file descriptor made the event and when application expects just period
2451 * timing.
2453 * Also this function might be called after #snd_pcm_delay() or
2454 * #snd_pcm_hwsync() functions to move private ring buffer pointers
2455 * in alsa-lib (the internal plugin chain).
2457 snd_pcm_sframes_t snd_pcm_avail_update(snd_pcm_t *pcm)
2459 return pcm->fast_ops->avail_update(pcm->fast_op_arg);
2463 * \brief Return number of frames ready to be read (capture) / written (playback)
2464 * \param pcm PCM handle
2465 * \return a positive number of frames ready otherwise a negative
2466 * error code
2468 * On capture does all the actions needed to transport to application
2469 * level all the ready frames across underlying layers.
2471 * The position is synced with hardware (driver) position in the sound
2472 * ring buffer in this functions.
2474 snd_pcm_sframes_t snd_pcm_avail(snd_pcm_t *pcm)
2476 int err;
2478 assert(pcm);
2479 if (CHECK_SANITY(! pcm->setup)) {
2480 SNDMSG("PCM not set up");
2481 return -EIO;
2483 err = pcm->fast_ops->hwsync(pcm->fast_op_arg);
2484 if (err < 0)
2485 return err;
2486 return pcm->fast_ops->avail_update(pcm->fast_op_arg);
2490 * \brief Combine snd_pcm_avail and snd_pcm_delay functions
2491 * \param pcm PCM handle
2492 * \param availp Number of available frames in the ring buffer
2493 * \param delayp Total I/O latency in frames
2494 * \return zero on success otherwise a negative error code
2496 * The avail and delay values retuned are in sync.
2498 int snd_pcm_avail_delay(snd_pcm_t *pcm,
2499 snd_pcm_sframes_t *availp,
2500 snd_pcm_sframes_t *delayp)
2502 snd_pcm_sframes_t sf;
2503 int err;
2505 assert(pcm && availp && delayp);
2506 if (CHECK_SANITY(! pcm->setup)) {
2507 SNDMSG("PCM not set up");
2508 return -EIO;
2510 err = pcm->fast_ops->hwsync(pcm->fast_op_arg);
2511 if (err < 0)
2512 return err;
2513 sf = pcm->fast_ops->avail_update(pcm->fast_op_arg);
2514 if (sf < 0)
2515 return (int)sf;
2516 err = pcm->fast_ops->delay(pcm->fast_op_arg, delayp);
2517 if (err < 0)
2518 return err;
2519 *availp = sf;
2520 return 0;
2524 * \brief Silence an area
2525 * \param dst_area area specification
2526 * \param dst_offset offset in frames inside area
2527 * \param samples samples to silence
2528 * \param format PCM sample format
2529 * \return 0 on success otherwise a negative error code
2531 int snd_pcm_area_silence(const snd_pcm_channel_area_t *dst_area, snd_pcm_uframes_t dst_offset,
2532 unsigned int samples, snd_pcm_format_t format)
2534 /* FIXME: sub byte resolution and odd dst_offset */
2535 char *dst;
2536 unsigned int dst_step;
2537 int width;
2538 u_int64_t silence;
2539 if (!dst_area->addr)
2540 return 0;
2541 dst = snd_pcm_channel_area_addr(dst_area, dst_offset);
2542 width = snd_pcm_format_physical_width(format);
2543 silence = snd_pcm_format_silence_64(format);
2544 if (dst_area->step == (unsigned int) width) {
2545 unsigned int dwords = samples * width / 64;
2546 u_int64_t *dstp = (u_int64_t *)dst;
2547 samples -= dwords * 64 / width;
2548 while (dwords-- > 0)
2549 *dstp++ = silence;
2550 if (samples == 0)
2551 return 0;
2553 dst_step = dst_area->step / 8;
2554 switch (width) {
2555 case 4: {
2556 u_int8_t s0 = silence & 0xf0;
2557 u_int8_t s1 = silence & 0x0f;
2558 int dstbit = dst_area->first % 8;
2559 int dstbit_step = dst_area->step % 8;
2560 while (samples-- > 0) {
2561 if (dstbit) {
2562 *dst &= 0xf0;
2563 *dst |= s1;
2564 } else {
2565 *dst &= 0x0f;
2566 *dst |= s0;
2568 dst += dst_step;
2569 dstbit += dstbit_step;
2570 if (dstbit == 8) {
2571 dst++;
2572 dstbit = 0;
2575 break;
2577 case 8: {
2578 u_int8_t sil = silence;
2579 while (samples-- > 0) {
2580 *dst = sil;
2581 dst += dst_step;
2583 break;
2585 case 16: {
2586 u_int16_t sil = silence;
2587 while (samples-- > 0) {
2588 *(u_int16_t*)dst = sil;
2589 dst += dst_step;
2591 break;
2593 case 24:
2594 #ifdef SNDRV_LITTLE_ENDIAN
2595 *(dst + 0) = silence >> 0;
2596 *(dst + 1) = silence >> 8;
2597 *(dst + 2) = silence >> 16;
2598 #else
2599 *(dst + 2) = silence >> 0;
2600 *(dst + 1) = silence >> 8;
2601 *(dst + 0) = silence >> 16;
2602 #endif
2603 break;
2604 case 32: {
2605 u_int32_t sil = silence;
2606 while (samples-- > 0) {
2607 *(u_int32_t*)dst = sil;
2608 dst += dst_step;
2610 break;
2612 case 64: {
2613 while (samples-- > 0) {
2614 *(u_int64_t*)dst = silence;
2615 dst += dst_step;
2617 break;
2619 default:
2620 SNDMSG("invalid format width %d", width);
2621 return -EINVAL;
2623 return 0;
2627 * \brief Silence one or more areas
2628 * \param dst_areas areas specification (one for each channel)
2629 * \param dst_offset offset in frames inside area
2630 * \param channels channels count
2631 * \param frames frames to silence
2632 * \param format PCM sample format
2633 * \return 0 on success otherwise a negative error code
2635 int snd_pcm_areas_silence(const snd_pcm_channel_area_t *dst_areas, snd_pcm_uframes_t dst_offset,
2636 unsigned int channels, snd_pcm_uframes_t frames, snd_pcm_format_t format)
2638 int width = snd_pcm_format_physical_width(format);
2639 while (channels > 0) {
2640 void *addr = dst_areas->addr;
2641 unsigned int step = dst_areas->step;
2642 const snd_pcm_channel_area_t *begin = dst_areas;
2643 int channels1 = channels;
2644 unsigned int chns = 0;
2645 int err;
2646 while (1) {
2647 channels1--;
2648 chns++;
2649 dst_areas++;
2650 if (channels1 == 0 ||
2651 dst_areas->addr != addr ||
2652 dst_areas->step != step ||
2653 dst_areas->first != dst_areas[-1].first + width)
2654 break;
2656 if (chns > 1 && chns * width == step) {
2657 /* Collapse the areas */
2658 snd_pcm_channel_area_t d;
2659 d.addr = begin->addr;
2660 d.first = begin->first;
2661 d.step = width;
2662 err = snd_pcm_area_silence(&d, dst_offset * chns, frames * chns, format);
2663 channels -= chns;
2664 } else {
2665 err = snd_pcm_area_silence(begin, dst_offset, frames, format);
2666 dst_areas = begin + 1;
2667 channels--;
2669 if (err < 0)
2670 return err;
2672 return 0;
2677 * \brief Copy an area
2678 * \param dst_area destination area specification
2679 * \param dst_offset offset in frames inside destination area
2680 * \param src_area source area specification
2681 * \param src_offset offset in frames inside source area
2682 * \param samples samples to copy
2683 * \param format PCM sample format
2684 * \return 0 on success otherwise a negative error code
2686 int snd_pcm_area_copy(const snd_pcm_channel_area_t *dst_area, snd_pcm_uframes_t dst_offset,
2687 const snd_pcm_channel_area_t *src_area, snd_pcm_uframes_t src_offset,
2688 unsigned int samples, snd_pcm_format_t format)
2690 /* FIXME: sub byte resolution and odd dst_offset */
2691 const char *src;
2692 char *dst;
2693 int width;
2694 int src_step, dst_step;
2695 if (dst_area == src_area && dst_offset == src_offset)
2696 return 0;
2697 if (!src_area->addr)
2698 return snd_pcm_area_silence(dst_area, dst_offset, samples, format);
2699 src = snd_pcm_channel_area_addr(src_area, src_offset);
2700 if (!dst_area->addr)
2701 return 0;
2702 dst = snd_pcm_channel_area_addr(dst_area, dst_offset);
2703 width = snd_pcm_format_physical_width(format);
2704 if (src_area->step == (unsigned int) width &&
2705 dst_area->step == (unsigned int) width) {
2706 size_t bytes = samples * width / 8;
2707 samples -= bytes * 8 / width;
2708 memcpy(dst, src, bytes);
2709 if (samples == 0)
2710 return 0;
2712 src_step = src_area->step / 8;
2713 dst_step = dst_area->step / 8;
2714 switch (width) {
2715 case 4: {
2716 int srcbit = src_area->first % 8;
2717 int srcbit_step = src_area->step % 8;
2718 int dstbit = dst_area->first % 8;
2719 int dstbit_step = dst_area->step % 8;
2720 while (samples-- > 0) {
2721 unsigned char srcval;
2722 if (srcbit)
2723 srcval = *src & 0x0f;
2724 else
2725 srcval = *src & 0xf0;
2726 if (dstbit)
2727 *dst &= 0xf0;
2728 else
2729 *dst &= 0x0f;
2730 *dst |= srcval;
2731 src += src_step;
2732 srcbit += srcbit_step;
2733 if (srcbit == 8) {
2734 src++;
2735 srcbit = 0;
2737 dst += dst_step;
2738 dstbit += dstbit_step;
2739 if (dstbit == 8) {
2740 dst++;
2741 dstbit = 0;
2744 break;
2746 case 8: {
2747 while (samples-- > 0) {
2748 *dst = *src;
2749 src += src_step;
2750 dst += dst_step;
2752 break;
2754 case 16: {
2755 while (samples-- > 0) {
2756 *(u_int16_t*)dst = *(const u_int16_t*)src;
2757 src += src_step;
2758 dst += dst_step;
2760 break;
2762 case 24:
2763 while (samples-- > 0) {
2764 *(dst + 0) = *(src + 0);
2765 *(dst + 1) = *(src + 1);
2766 *(dst + 2) = *(src + 2);
2767 src += src_step;
2768 dst += dst_step;
2770 break;
2771 case 32: {
2772 while (samples-- > 0) {
2773 *(u_int32_t*)dst = *(const u_int32_t*)src;
2774 src += src_step;
2775 dst += dst_step;
2777 break;
2779 case 64: {
2780 while (samples-- > 0) {
2781 *(u_int64_t*)dst = *(const u_int64_t*)src;
2782 src += src_step;
2783 dst += dst_step;
2785 break;
2787 default:
2788 SNDMSG("invalid format width %d", width);
2789 return -EINVAL;
2791 return 0;
2795 * \brief Copy one or more areas
2796 * \param dst_areas destination areas specification (one for each channel)
2797 * \param dst_offset offset in frames inside destination area
2798 * \param src_areas source areas specification (one for each channel)
2799 * \param src_offset offset in frames inside source area
2800 * \param channels channels count
2801 * \param frames frames to copy
2802 * \param format PCM sample format
2803 * \return 0 on success otherwise a negative error code
2805 int snd_pcm_areas_copy(const snd_pcm_channel_area_t *dst_areas, snd_pcm_uframes_t dst_offset,
2806 const snd_pcm_channel_area_t *src_areas, snd_pcm_uframes_t src_offset,
2807 unsigned int channels, snd_pcm_uframes_t frames, snd_pcm_format_t format)
2809 int width = snd_pcm_format_physical_width(format);
2810 assert(dst_areas);
2811 assert(src_areas);
2812 if (! channels) {
2813 SNDMSG("invalid channels %d", channels);
2814 return -EINVAL;
2816 if (! frames) {
2817 SNDMSG("invalid frames %ld", frames);
2818 return -EINVAL;
2820 while (channels > 0) {
2821 unsigned int step = src_areas->step;
2822 void *src_addr = src_areas->addr;
2823 const snd_pcm_channel_area_t *src_start = src_areas;
2824 void *dst_addr = dst_areas->addr;
2825 const snd_pcm_channel_area_t *dst_start = dst_areas;
2826 int channels1 = channels;
2827 unsigned int chns = 0;
2828 while (dst_areas->step == step) {
2829 channels1--;
2830 chns++;
2831 src_areas++;
2832 dst_areas++;
2833 if (channels1 == 0 ||
2834 src_areas->step != step ||
2835 src_areas->addr != src_addr ||
2836 dst_areas->addr != dst_addr ||
2837 src_areas->first != src_areas[-1].first + width ||
2838 dst_areas->first != dst_areas[-1].first + width)
2839 break;
2841 if (chns > 1 && chns * width == step) {
2842 /* Collapse the areas */
2843 snd_pcm_channel_area_t s, d;
2844 s.addr = src_start->addr;
2845 s.first = src_start->first;
2846 s.step = width;
2847 d.addr = dst_start->addr;
2848 d.first = dst_start->first;
2849 d.step = width;
2850 snd_pcm_area_copy(&d, dst_offset * chns,
2851 &s, src_offset * chns,
2852 frames * chns, format);
2853 channels -= chns;
2854 } else {
2855 snd_pcm_area_copy(dst_start, dst_offset,
2856 src_start, src_offset,
2857 frames, format);
2858 src_areas = src_start + 1;
2859 dst_areas = dst_start + 1;
2860 channels--;
2863 return 0;
2866 static void dump_one_param(snd_pcm_hw_params_t *params, unsigned int k, snd_output_t *out)
2868 snd_output_printf(out, "%s: ", snd_pcm_hw_param_name(k));
2869 snd_pcm_hw_param_dump(params, k, out);
2870 snd_output_putc(out, '\n');
2874 * \brief Dump a PCM hardware configuration space
2875 * \param params Configuration space
2876 * \param out Output handle
2877 * \return 0 on success otherwise a negative error code
2879 int snd_pcm_hw_params_dump(snd_pcm_hw_params_t *params, snd_output_t *out)
2881 unsigned int k;
2882 for (k = SND_PCM_HW_PARAM_FIRST_MASK; k <= SND_PCM_HW_PARAM_LAST_MASK; k++)
2883 dump_one_param(params, k, out);
2884 for (k = SND_PCM_HW_PARAM_FIRST_INTERVAL; k <= SND_PCM_HW_PARAM_LAST_INTERVAL; k++)
2885 dump_one_param(params, k, out);
2886 return 0;
2890 * \brief Check if hardware supports sample-resolution mmap for given configuration
2891 * \param params Configuration space
2892 * \retval 0 Hardware doesn't support sample-resolution mmap
2893 * \retval 1 Hardware supports sample-resolution mmap
2895 * This function should only be called when the configuration space
2896 * contains a single configuration. Call #snd_pcm_hw_params to choose
2897 * a single configuration from the configuration space.
2899 int snd_pcm_hw_params_can_mmap_sample_resolution(const snd_pcm_hw_params_t *params)
2901 assert(params);
2902 if (CHECK_SANITY(params->info == ~0U)) {
2903 SNDMSG("invalid PCM info field");
2904 return 0; /* FIXME: should be a negative error? */
2906 return !!(params->info & SNDRV_PCM_INFO_MMAP_VALID);
2910 * \brief Check if hardware does double buffering for start/stop for given configuration
2911 * \param params Configuration space
2912 * \retval 0 Hardware doesn't do double buffering for start/stop
2913 * \retval 1 Hardware does double buffering for start/stop
2915 * This function should only be called when the configuration space
2916 * contains a single configuration. Call #snd_pcm_hw_params to choose
2917 * a single configuration from the configuration space.
2919 int snd_pcm_hw_params_is_double(const snd_pcm_hw_params_t *params)
2921 assert(params);
2922 if (CHECK_SANITY(params->info == ~0U)) {
2923 SNDMSG("invalid PCM info field");
2924 return 0; /* FIXME: should be a negative error? */
2926 return !!(params->info & SNDRV_PCM_INFO_DOUBLE);
2930 * \brief Check if hardware does double buffering for data transfers for given configuration
2931 * \param params Configuration space
2932 * \retval 0 Hardware doesn't do double buffering for data transfers
2933 * \retval 1 Hardware does double buffering for data transfers
2935 * This function should only be called when the configuration space
2936 * contains a single configuration. Call #snd_pcm_hw_params to choose
2937 * a single configuration from the configuration space.
2939 int snd_pcm_hw_params_is_batch(const snd_pcm_hw_params_t *params)
2941 assert(params);
2942 if (CHECK_SANITY(params->info == ~0U)) {
2943 SNDMSG("invalid PCM info field");
2944 return 0; /* FIXME: should be a negative error? */
2946 return !!(params->info & SNDRV_PCM_INFO_BATCH);
2950 * \brief Check if hardware does block transfers for samples for given configuration
2951 * \param params Configuration space
2952 * \retval 0 Hardware doesn't block transfers
2953 * \retval 1 Hardware does block transfers
2955 * This function should only be called when the configuration space
2956 * contains a single configuration. Call #snd_pcm_hw_params to choose
2957 * a single configuration from the configuration space.
2959 int snd_pcm_hw_params_is_block_transfer(const snd_pcm_hw_params_t *params)
2961 assert(params);
2962 if (CHECK_SANITY(params->info == ~0U)) {
2963 SNDMSG("invalid PCM info field");
2964 return 0; /* FIXME: should be a negative error? */
2966 return !!(params->info & SNDRV_PCM_INFO_BLOCK_TRANSFER);
2970 * \brief Check if timestamps are monotonic for given configuration
2971 * \param params Configuration space
2972 * \retval 0 Device doesn't do monotomic timestamps
2973 * \retval 1 Device does monotonic timestamps
2975 * This function should only be called when the configuration space
2976 * contains a single configuration. Call #snd_pcm_hw_params to choose
2977 * a single configuration from the configuration space.
2979 int snd_pcm_hw_params_is_monotonic(const snd_pcm_hw_params_t *params)
2981 assert(params);
2982 if (CHECK_SANITY(params->info == ~0U)) {
2983 SNDMSG("invalid PCM info field");
2984 return 0; /* FIXME: should be a negative error? */
2986 return !!(params->info & SND_PCM_INFO_MONOTONIC);
2990 * \brief Check if hardware supports overrange detection
2991 * \param params Configuration space
2992 * \retval 0 Hardware doesn't support overrange detection
2993 * \retval 1 Hardware supports overrange detection
2995 * This function should only be called when the configuration space
2996 * contains a single configuration. Call #snd_pcm_hw_params to choose
2997 * a single configuration from the configuration space.
2999 int snd_pcm_hw_params_can_overrange(const snd_pcm_hw_params_t *params)
3001 assert(params);
3002 if (CHECK_SANITY(params->info == ~0U)) {
3003 SNDMSG("invalid PCM info field");
3004 return 0; /* FIXME: should be a negative error? */
3006 return !!(params->info & SNDRV_PCM_INFO_OVERRANGE);
3010 * \brief Check if hardware supports pause
3011 * \param params Configuration space
3012 * \retval 0 Hardware doesn't support pause
3013 * \retval 1 Hardware supports pause
3015 * This function should only be called when the configuration space
3016 * contains a single configuration. Call #snd_pcm_hw_params to choose
3017 * a single configuration from the configuration space.
3019 int snd_pcm_hw_params_can_pause(const snd_pcm_hw_params_t *params)
3021 assert(params);
3022 if (CHECK_SANITY(params->info == ~0U)) {
3023 SNDMSG("invalid PCM info field");
3024 return 0; /* FIXME: should be a negative error? */
3026 return !!(params->info & SNDRV_PCM_INFO_PAUSE);
3030 * \brief Check if hardware supports resume
3031 * \param params Configuration space
3032 * \retval 0 Hardware doesn't support resume
3033 * \retval 1 Hardware supports resume
3035 * This function should only be called when the configuration space
3036 * contains a single configuration. Call #snd_pcm_hw_params to choose
3037 * a single configuration from the configuration space.
3039 int snd_pcm_hw_params_can_resume(const snd_pcm_hw_params_t *params)
3041 assert(params);
3042 if (CHECK_SANITY(params->info == ~0U)) {
3043 SNDMSG("invalid PCM info field");
3044 return 0; /* FIXME: should be a negative error? */
3046 return !!(params->info & SNDRV_PCM_INFO_RESUME);
3050 * \brief Check if hardware does half-duplex only
3051 * \param params Configuration space
3052 * \retval 0 Hardware doesn't do half-duplex
3053 * \retval 1 Hardware does half-duplex
3055 * This function should only be called when the configuration space
3056 * contains a single configuration. Call #snd_pcm_hw_params to choose
3057 * a single configuration from the configuration space.
3059 int snd_pcm_hw_params_is_half_duplex(const snd_pcm_hw_params_t *params)
3061 assert(params);
3062 if (CHECK_SANITY(params->info == ~0U)) {
3063 SNDMSG("invalid PCM info field");
3064 return 0; /* FIXME: should be a negative error? */
3066 return !!(params->info & SNDRV_PCM_INFO_HALF_DUPLEX);
3070 * \brief Check if hardware does joint-duplex (playback and capture are somewhat correlated)
3071 * \param params Configuration space
3072 * \retval 0 Hardware doesn't do joint-duplex
3073 * \retval 1 Hardware does joint-duplex
3075 * This function should only be called when the configuration space
3076 * contains a single configuration. Call #snd_pcm_hw_params to choose
3077 * a single configuration from the configuration space.
3079 int snd_pcm_hw_params_is_joint_duplex(const snd_pcm_hw_params_t *params)
3081 assert(params);
3082 if (CHECK_SANITY(params->info == ~0U)) {
3083 SNDMSG("invalid PCM info field");
3084 return 0; /* FIXME: should be a negative error? */
3086 return !!(params->info & SNDRV_PCM_INFO_JOINT_DUPLEX);
3090 * \brief Check if hardware supports synchronized start with sample resolution
3091 * \param params Configuration space
3092 * \retval 0 Hardware doesn't support synchronized start
3093 * \retval 1 Hardware supports synchronized start
3095 * This function should only be called when the configuration space
3096 * contains a single configuration. Call #snd_pcm_hw_params to choose
3097 * a single configuration from the configuration space.
3099 int snd_pcm_hw_params_can_sync_start(const snd_pcm_hw_params_t *params)
3101 assert(params);
3102 if (CHECK_SANITY(params->info == ~0U)) {
3103 SNDMSG("invalid PCM info field");
3104 return 0; /* FIXME: should be a negative error? */
3106 return !!(params->info & SNDRV_PCM_INFO_SYNC_START);
3110 * \brief Check if hardware can disable period wakeups
3111 * \param params Configuration space
3112 * \retval 0 Hardware cannot disable period wakeups
3113 * \retval 1 Hardware can disable period wakeups
3115 int snd_pcm_hw_params_can_disable_period_wakeup(const snd_pcm_hw_params_t *params)
3117 assert(params);
3118 if (CHECK_SANITY(params->info == ~0U)) {
3119 SNDMSG("invalid PCM info field");
3120 return 0; /* FIXME: should be a negative error? */
3122 return !!(params->info & SNDRV_PCM_INFO_NO_PERIOD_WAKEUP);
3126 * \brief Get rate exact info from a configuration space
3127 * \param params Configuration space
3128 * \param rate_num Pointer to returned rate numerator
3129 * \param rate_den Pointer to returned rate denominator
3130 * \return 0 otherwise a negative error code if the info is not available
3132 * This function should only be called when the configuration space
3133 * contains a single configuration. Call #snd_pcm_hw_params to choose
3134 * a single configuration from the configuration space.
3136 int snd_pcm_hw_params_get_rate_numden(const snd_pcm_hw_params_t *params,
3137 unsigned int *rate_num, unsigned int *rate_den)
3139 assert(params);
3140 if (CHECK_SANITY(params->rate_den == 0)) {
3141 SNDMSG("invalid rate_den value");
3142 return -EINVAL;
3144 *rate_num = params->rate_num;
3145 *rate_den = params->rate_den;
3146 return 0;
3150 * \brief Get sample resolution info from a configuration space
3151 * \param params Configuration space
3152 * \return signification bits in sample otherwise a negative error code if the info is not available
3154 * This function should only be called when the configuration space
3155 * contains a single configuration. Call #snd_pcm_hw_params to choose
3156 * a single configuration from the configuration space.
3158 int snd_pcm_hw_params_get_sbits(const snd_pcm_hw_params_t *params)
3160 assert(params);
3161 if (CHECK_SANITY(params->msbits == 0)) {
3162 SNDMSG("invalid msbits value");
3163 return -EINVAL;
3165 return params->msbits;
3169 * \brief Get hardware FIFO size info from a configuration space
3170 * \param params Configuration space
3171 * \return FIFO size in frames otherwise a negative error code if the info is not available
3173 * This function should only be called when the configuration space
3174 * contains a single configuration. Call #snd_pcm_hw_params to choose
3175 * a single configuration from the configuration space.
3177 int snd_pcm_hw_params_get_fifo_size(const snd_pcm_hw_params_t *params)
3179 assert(params);
3180 if (CHECK_SANITY(params->info == ~0U)) {
3181 SNDMSG("invalid PCM info field");
3182 return -EINVAL;
3184 return params->fifo_size;
3188 * \brief Fill params with a full configuration space for a PCM
3189 * \param pcm PCM handle
3190 * \param params Configuration space
3192 * The configuration space will be filled with all possible ranges
3193 * for the PCM device.
3195 int snd_pcm_hw_params_any(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
3197 _snd_pcm_hw_params_any(params);
3198 return snd_pcm_hw_refine(pcm, params);
3202 * \brief get size of #snd_pcm_access_mask_t
3203 * \return size in bytes
3205 size_t snd_pcm_access_mask_sizeof()
3207 return sizeof(snd_pcm_access_mask_t);
3211 * \brief allocate an empty #snd_pcm_access_mask_t using standard malloc
3212 * \param ptr returned pointer
3213 * \return 0 on success otherwise negative error code
3215 int snd_pcm_access_mask_malloc(snd_pcm_access_mask_t **ptr)
3217 assert(ptr);
3218 *ptr = calloc(1, sizeof(snd_pcm_access_mask_t));
3219 if (!*ptr)
3220 return -ENOMEM;
3221 return 0;
3225 * \brief frees a previously allocated #snd_pcm_access_mask_t
3226 * \param obj pointer to object to free
3228 void snd_pcm_access_mask_free(snd_pcm_access_mask_t *obj)
3230 free(obj);
3234 * \brief copy one #snd_pcm_access_mask_t to another
3235 * \param dst pointer to destination
3236 * \param src pointer to source
3238 void snd_pcm_access_mask_copy(snd_pcm_access_mask_t *dst, const snd_pcm_access_mask_t *src)
3240 assert(dst && src);
3241 *dst = *src;
3245 * \brief reset all bits in a #snd_pcm_access_mask_t
3246 * \param mask pointer to mask
3248 void snd_pcm_access_mask_none(snd_pcm_access_mask_t *mask)
3250 snd_mask_none((snd_mask_t *) mask);
3254 * \brief set all bits in a #snd_pcm_access_mask_t
3255 * \param mask pointer to mask
3257 void snd_pcm_access_mask_any(snd_pcm_access_mask_t *mask)
3259 snd_mask_any((snd_mask_t *) mask);
3263 * \brief test the presence of an access type in a #snd_pcm_access_mask_t
3264 * \param mask pointer to mask
3265 * \param val access type
3267 int snd_pcm_access_mask_test(const snd_pcm_access_mask_t *mask, snd_pcm_access_t val)
3269 return snd_mask_test((const snd_mask_t *) mask, (unsigned long) val);
3273 * \brief test, if given a #snd_pcm_access_mask_t is empty
3274 * \param mask pointer to mask
3275 * \retval 0 not empty
3276 * \retval 1 empty
3278 int snd_pcm_access_mask_empty(const snd_pcm_access_mask_t *mask)
3280 return snd_mask_empty((const snd_mask_t *) mask);
3284 * \brief make an access type present in a #snd_pcm_access_mask_t
3285 * \param mask pointer to mask
3286 * \param val access type
3288 void snd_pcm_access_mask_set(snd_pcm_access_mask_t *mask, snd_pcm_access_t val)
3290 snd_mask_set((snd_mask_t *) mask, (unsigned long) val);
3294 * \brief make an access type missing from a #snd_pcm_access_mask_t
3295 * \param mask pointer to mask
3296 * \param val access type
3298 void snd_pcm_access_mask_reset(snd_pcm_access_mask_t *mask, snd_pcm_access_t val)
3300 snd_mask_reset((snd_mask_t *) mask, (unsigned long) val);
3304 * \brief get size of #snd_pcm_format_mask_t
3305 * \return size in bytes
3307 size_t snd_pcm_format_mask_sizeof()
3309 return sizeof(snd_pcm_format_mask_t);
3313 * \brief allocate an empty #snd_pcm_format_mask_t using standard malloc
3314 * \param ptr returned pointer
3315 * \return 0 on success otherwise negative error code
3317 int snd_pcm_format_mask_malloc(snd_pcm_format_mask_t **ptr)
3319 assert(ptr);
3320 *ptr = calloc(1, sizeof(snd_pcm_format_mask_t));
3321 if (!*ptr)
3322 return -ENOMEM;
3323 return 0;
3327 * \brief frees a previously allocated #snd_pcm_format_mask_t
3328 * \param obj pointer to object to free
3330 void snd_pcm_format_mask_free(snd_pcm_format_mask_t *obj)
3332 free(obj);
3336 * \brief copy one #snd_pcm_format_mask_t to another
3337 * \param dst pointer to destination
3338 * \param src pointer to source
3340 void snd_pcm_format_mask_copy(snd_pcm_format_mask_t *dst, const snd_pcm_format_mask_t *src)
3342 assert(dst && src);
3343 *dst = *src;
3347 * \brief reset all bits in a #snd_pcm_format_mask_t
3348 * \param mask pointer to mask
3350 void snd_pcm_format_mask_none(snd_pcm_format_mask_t *mask)
3352 snd_mask_none((snd_mask_t *) mask);
3356 * \brief set all bits in a #snd_pcm_format_mask_t
3357 * \param mask pointer to mask
3359 void snd_pcm_format_mask_any(snd_pcm_format_mask_t *mask)
3361 snd_mask_any((snd_mask_t *) mask);
3365 * \brief test the presence of a format in a #snd_pcm_format_mask_t
3366 * \param mask pointer to mask
3367 * \param val format
3369 int snd_pcm_format_mask_test(const snd_pcm_format_mask_t *mask, snd_pcm_format_t val)
3371 return snd_mask_test((const snd_mask_t *) mask, (unsigned long) val);
3375 * \brief test, if given a #snd_pcm_format_mask_t is empty
3376 * \param mask pointer to mask
3377 * \retval 0 not empty
3378 * \retval 1 empty
3380 int snd_pcm_format_mask_empty(const snd_pcm_format_mask_t *mask)
3382 return snd_mask_empty((const snd_mask_t *) mask);
3386 * \brief make a format present in a #snd_pcm_format_mask_t
3387 * \param mask pointer to mask
3388 * \param val format
3390 void snd_pcm_format_mask_set(snd_pcm_format_mask_t *mask, snd_pcm_format_t val)
3392 snd_mask_set((snd_mask_t *) mask, (unsigned long) val);
3396 * \brief make a format missing from a #snd_pcm_format_mask_t
3397 * \param mask pointer to mask
3398 * \param val format
3400 void snd_pcm_format_mask_reset(snd_pcm_format_mask_t *mask, snd_pcm_format_t val)
3402 snd_mask_reset((snd_mask_t *) mask, (unsigned long) val);
3407 * \brief get size of #snd_pcm_subformat_mask_t
3408 * \return size in bytes
3410 size_t snd_pcm_subformat_mask_sizeof()
3412 return sizeof(snd_pcm_subformat_mask_t);
3416 * \brief allocate an empty #snd_pcm_subformat_mask_t using standard malloc
3417 * \param ptr returned pointer
3418 * \return 0 on success otherwise negative error code
3420 int snd_pcm_subformat_mask_malloc(snd_pcm_subformat_mask_t **ptr)
3422 assert(ptr);
3423 *ptr = calloc(1, sizeof(snd_pcm_subformat_mask_t));
3424 if (!*ptr)
3425 return -ENOMEM;
3426 return 0;
3430 * \brief frees a previously allocated #snd_pcm_subformat_mask_t
3431 * \param obj pointer to object to free
3433 void snd_pcm_subformat_mask_free(snd_pcm_subformat_mask_t *obj)
3435 free(obj);
3439 * \brief copy one #snd_pcm_subformat_mask_t to another
3440 * \param dst pointer to destination
3441 * \param src pointer to source
3443 void snd_pcm_subformat_mask_copy(snd_pcm_subformat_mask_t *dst, const snd_pcm_subformat_mask_t *src)
3445 assert(dst && src);
3446 *dst = *src;
3450 * \brief reset all bits in a #snd_pcm_subformat_mask_t
3451 * \param mask pointer to mask
3453 void snd_pcm_subformat_mask_none(snd_pcm_subformat_mask_t *mask)
3455 snd_mask_none((snd_mask_t *) mask);
3459 * \brief set all bits in a #snd_pcm_subformat_mask_t
3460 * \param mask pointer to mask
3462 void snd_pcm_subformat_mask_any(snd_pcm_subformat_mask_t *mask)
3464 snd_mask_any((snd_mask_t *) mask);
3468 * \brief test the presence of a subformat in a #snd_pcm_subformat_mask_t
3469 * \param mask pointer to mask
3470 * \param val subformat
3472 int snd_pcm_subformat_mask_test(const snd_pcm_subformat_mask_t *mask, snd_pcm_subformat_t val)
3474 return snd_mask_test((const snd_mask_t *) mask, (unsigned long) val);
3478 * \brief test, if given a #snd_pcm_subformat_mask_t is empty
3479 * \param mask pointer to mask
3480 * \retval 0 not empty
3481 * \retval 1 empty
3483 int snd_pcm_subformat_mask_empty(const snd_pcm_subformat_mask_t *mask)
3485 return snd_mask_empty((const snd_mask_t *) mask);
3489 * \brief make a subformat present in a #snd_pcm_subformat_mask_t
3490 * \param mask pointer to mask
3491 * \param val subformat
3493 void snd_pcm_subformat_mask_set(snd_pcm_subformat_mask_t *mask, snd_pcm_subformat_t val)
3495 snd_mask_set((snd_mask_t *) mask, (unsigned long) val);
3499 * \brief make a subformat missing from a #snd_pcm_subformat_mask_t
3500 * \param mask pointer to mask
3501 * \param val subformat
3503 void snd_pcm_subformat_mask_reset(snd_pcm_subformat_mask_t *mask, snd_pcm_subformat_t val)
3505 snd_mask_reset((snd_mask_t *) mask, (unsigned long) val);
3510 * \brief get size of #snd_pcm_hw_params_t
3511 * \return size in bytes
3513 size_t snd_pcm_hw_params_sizeof()
3515 return sizeof(snd_pcm_hw_params_t);
3519 * \brief allocate an invalid #snd_pcm_hw_params_t using standard malloc
3520 * \param ptr returned pointer
3521 * \return 0 on success otherwise negative error code
3523 int snd_pcm_hw_params_malloc(snd_pcm_hw_params_t **ptr)
3525 assert(ptr);
3526 *ptr = calloc(1, sizeof(snd_pcm_hw_params_t));
3527 if (!*ptr)
3528 return -ENOMEM;
3529 return 0;
3533 * \brief frees a previously allocated #snd_pcm_hw_params_t
3534 * \param obj pointer to object to free
3536 void snd_pcm_hw_params_free(snd_pcm_hw_params_t *obj)
3538 free(obj);
3542 * \brief copy one #snd_pcm_hw_params_t to another
3543 * \param dst pointer to destination
3544 * \param src pointer to source
3546 void snd_pcm_hw_params_copy(snd_pcm_hw_params_t *dst, const snd_pcm_hw_params_t *src)
3548 assert(dst && src);
3549 *dst = *src;
3554 * \brief Extract access type from a configuration space
3555 * \param params Configuration space
3556 * \param access Returned value
3557 * \return access type otherwise a negative error code if the configuration space does not contain a single value
3559 #ifndef DOXYGEN
3560 int INTERNAL(snd_pcm_hw_params_get_access)(const snd_pcm_hw_params_t *params, snd_pcm_access_t *access)
3561 #else
3562 int snd_pcm_hw_params_get_access(const snd_pcm_hw_params_t *params, snd_pcm_access_t *access)
3563 #endif
3565 unsigned int _val;
3566 int err = snd_pcm_hw_param_get(params, SND_PCM_HW_PARAM_ACCESS, &_val, NULL);
3567 if (err >= 0)
3568 *access = _val;
3569 return err;
3573 * \brief Verify if an access type is available inside a configuration space for a PCM
3574 * \param pcm PCM handle
3575 * \param params Configuration space
3576 * \param access access type
3577 * \return 0 if available a negative error code otherwise
3579 int snd_pcm_hw_params_test_access(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_t access)
3581 return snd_pcm_hw_param_set(pcm, params, SND_TEST, SND_PCM_HW_PARAM_ACCESS, access, 0);
3585 * \brief Restrict a configuration space to contain only one access type
3586 * \param pcm PCM handle
3587 * \param params Configuration space
3588 * \param access access type
3589 * \return 0 otherwise a negative error code if configuration space would become empty
3591 int snd_pcm_hw_params_set_access(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_t access)
3593 return snd_pcm_hw_param_set(pcm, params, SND_TRY, SND_PCM_HW_PARAM_ACCESS, access, 0);
3597 * \brief Restrict a configuration space to contain only its first access type
3598 * \param pcm PCM handle
3599 * \param params Configuration space
3600 * \param access Returned first access type
3601 * \return 0 otherwise a negative error code
3603 #ifndef DOXYGEN
3604 int INTERNAL(snd_pcm_hw_params_set_access_first)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_t *access)
3605 #else
3606 int snd_pcm_hw_params_set_access_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_t *access)
3607 #endif
3609 return snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_ACCESS, access, NULL);
3613 * \brief Restrict a configuration space to contain only its last access type
3614 * \param pcm PCM handle
3615 * \param params Configuration space
3616 * \param access Returned last access type
3617 * \return 0 otherwise a negative error code
3619 #ifndef DOXYGEN
3620 int INTERNAL(snd_pcm_hw_params_set_access_last)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_t *access)
3621 #else
3622 int snd_pcm_hw_params_set_access_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_t *access)
3623 #endif
3625 return snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_ACCESS, access, NULL);
3629 * \brief Restrict a configuration space to contain only a set of access types
3630 * \param pcm PCM handle
3631 * \param params Configuration space
3632 * \param mask Access mask
3633 * \return 0 otherwise a negative error code
3635 int snd_pcm_hw_params_set_access_mask(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_mask_t *mask)
3637 return snd_pcm_hw_param_set_mask(pcm, params, SND_TRY, SND_PCM_HW_PARAM_ACCESS, (snd_mask_t *) mask);
3641 * \brief Get access mask from a configuration space
3642 * \param params Configuration space
3643 * \param mask Returned Access mask
3645 int snd_pcm_hw_params_get_access_mask(snd_pcm_hw_params_t *params, snd_pcm_access_mask_t *mask)
3647 if (params == NULL || mask == NULL)
3648 return -EINVAL;
3649 snd_pcm_access_mask_copy(mask, snd_pcm_hw_param_get_mask(params, SND_PCM_HW_PARAM_ACCESS));
3650 return 0;
3655 * \brief Extract format from a configuration space
3656 * \param params Configuration space
3657 * \param format returned format
3658 * \return format otherwise a negative error code if the configuration space does not contain a single value
3660 #ifndef DOXYGEN
3661 int INTERNAL(snd_pcm_hw_params_get_format)(const snd_pcm_hw_params_t *params, snd_pcm_format_t *format)
3662 #else
3663 int snd_pcm_hw_params_get_format(const snd_pcm_hw_params_t *params, snd_pcm_format_t *format)
3664 #endif
3666 return snd_pcm_hw_param_get(params, SND_PCM_HW_PARAM_FORMAT, (unsigned int *)format, NULL);
3670 * \brief Verify if a format is available inside a configuration space for a PCM
3671 * \param pcm PCM handle
3672 * \param params Configuration space
3673 * \param format format
3674 * \return 0 if available a negative error code otherwise
3676 int snd_pcm_hw_params_test_format(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_t format)
3678 return snd_pcm_hw_param_set(pcm, params, SND_TEST, SND_PCM_HW_PARAM_FORMAT, format, 0);
3682 * \brief Restrict a configuration space to contain only one format
3683 * \param pcm PCM handle
3684 * \param params Configuration space
3685 * \param format format
3686 * \return 0 otherwise a negative error code
3688 int snd_pcm_hw_params_set_format(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_t format)
3690 return snd_pcm_hw_param_set(pcm, params, SND_TRY, SND_PCM_HW_PARAM_FORMAT, format, 0);
3694 * \brief Restrict a configuration space to contain only its first format
3695 * \param pcm PCM handle
3696 * \param params Configuration space
3697 * \param format Returned first format
3698 * \return 0 otherwise a negative error code
3700 #ifndef DOXYGEN
3701 int INTERNAL(snd_pcm_hw_params_set_format_first)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_t *format)
3702 #else
3703 int snd_pcm_hw_params_set_format_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_t *format)
3704 #endif
3706 return snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_FORMAT, (unsigned int *)format, NULL);
3710 * \brief Restrict a configuration space to contain only its last format
3711 * \param pcm PCM handle
3712 * \param params Configuration space
3713 * \param format Returned last format
3714 * \return 0 otherwise a negative error code
3716 #ifndef DOXYGEN
3717 int INTERNAL(snd_pcm_hw_params_set_format_last)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_t *format)
3718 #else
3719 int snd_pcm_hw_params_set_format_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_t *format)
3720 #endif
3722 return snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_FORMAT, (unsigned int *)format, NULL);
3726 * \brief Restrict a configuration space to contain only a set of formats
3727 * \param pcm PCM handle
3728 * \param params Configuration space
3729 * \param mask Format mask
3730 * \return 0 otherwise a negative error code
3732 int snd_pcm_hw_params_set_format_mask(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_mask_t *mask)
3734 return snd_pcm_hw_param_set_mask(pcm, params, SND_TRY, SND_PCM_HW_PARAM_FORMAT, (snd_mask_t *) mask);
3738 * \brief Get format mask from a configuration space
3739 * \param params Configuration space
3740 * \param mask Returned Format mask
3742 void snd_pcm_hw_params_get_format_mask(snd_pcm_hw_params_t *params, snd_pcm_format_mask_t *mask)
3744 snd_pcm_format_mask_copy(mask, snd_pcm_hw_param_get_mask(params, SND_PCM_HW_PARAM_FORMAT));
3749 * \brief Extract subformat from a configuration space
3750 * \param params Configuration space
3751 * \param subformat Returned subformat value
3752 * \return subformat otherwise a negative error code if the configuration space does not contain a single value
3754 #ifndef DOXYGEN
3755 int INTERNAL(snd_pcm_hw_params_get_subformat)(const snd_pcm_hw_params_t *params, snd_pcm_subformat_t *subformat)
3756 #else
3757 int snd_pcm_hw_params_get_subformat(const snd_pcm_hw_params_t *params, snd_pcm_subformat_t *subformat)
3758 #endif
3760 return snd_pcm_hw_param_get(params, SND_PCM_HW_PARAM_SUBFORMAT, subformat, NULL);
3764 * \brief Verify if a subformat is available inside a configuration space for a PCM
3765 * \param pcm PCM handle
3766 * \param params Configuration space
3767 * \param subformat subformat value
3768 * \return 0 if available a negative error code otherwise
3770 int snd_pcm_hw_params_test_subformat(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_t subformat)
3772 return snd_pcm_hw_param_set(pcm, params, SND_TEST, SND_PCM_HW_PARAM_SUBFORMAT, subformat, 0);
3776 * \brief Restrict a configuration space to contain only one subformat
3777 * \param pcm PCM handle
3778 * \param params Configuration space
3779 * \param subformat subformat value
3780 * \return 0 otherwise a negative error code if configuration space would become empty
3782 int snd_pcm_hw_params_set_subformat(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_t subformat)
3784 return snd_pcm_hw_param_set(pcm, params, SND_TRY, SND_PCM_HW_PARAM_SUBFORMAT, subformat, 0);
3788 * \brief Restrict a configuration space to contain only its first subformat
3789 * \param pcm PCM handle
3790 * \param params Configuration space
3791 * \param subformat Returned subformat
3792 * \return 0 otherwise a negative error code
3794 #ifndef DOXYGEN
3795 int INTERNAL(snd_pcm_hw_params_set_subformat_first)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_t *subformat)
3796 #else
3797 int snd_pcm_hw_params_set_subformat_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_t *subformat)
3798 #endif
3800 return snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_SUBFORMAT, subformat, NULL);
3804 * \brief Restrict a configuration space to contain only its last subformat
3805 * \param pcm PCM handle
3806 * \param params Configuration space
3807 * \param subformat Returned subformat
3808 * \return 0 otherwise a negative error code
3810 #ifndef DOXYGEN
3811 int INTERNAL(snd_pcm_hw_params_set_subformat_last)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_t *subformat)
3812 #else
3813 int snd_pcm_hw_params_set_subformat_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_t *subformat)
3814 #endif
3816 return snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_SUBFORMAT, subformat, NULL);
3820 * \brief Restrict a configuration space to contain only a set of subformats
3821 * \param pcm PCM handle
3822 * \param params Configuration space
3823 * \param mask Subformat mask
3824 * \return 0 otherwise a negative error code
3826 int snd_pcm_hw_params_set_subformat_mask(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_mask_t *mask)
3828 return snd_pcm_hw_param_set_mask(pcm, params, SND_TRY, SND_PCM_HW_PARAM_SUBFORMAT, (snd_mask_t *) mask);
3832 * \brief Get subformat mask from a configuration space
3833 * \param params Configuration space
3834 * \param mask Returned Subformat mask
3836 void snd_pcm_hw_params_get_subformat_mask(snd_pcm_hw_params_t *params, snd_pcm_subformat_mask_t *mask)
3838 snd_pcm_subformat_mask_copy(mask, snd_pcm_hw_param_get_mask(params, SND_PCM_HW_PARAM_SUBFORMAT));
3843 * \brief Extract channels from a configuration space
3844 * \param params Configuration space
3845 * \param val Returned channels count
3846 * \return 0 otherwise a negative error code if the configuration space does not contain a single value
3848 #ifndef DOXYGEN
3849 int INTERNAL(snd_pcm_hw_params_get_channels)(const snd_pcm_hw_params_t *params, unsigned int *val)
3850 #else
3851 int snd_pcm_hw_params_get_channels(const snd_pcm_hw_params_t *params, unsigned int *val)
3852 #endif
3854 return snd_pcm_hw_param_get(params, SND_PCM_HW_PARAM_CHANNELS, val, NULL);
3858 * \brief Extract minimum channels count from a configuration space
3859 * \param params Configuration space
3860 * \param val minimum channels count
3861 * \return 0 otherwise a negative error code
3863 #ifndef DOXYGEN
3864 int INTERNAL(snd_pcm_hw_params_get_channels_min)(const snd_pcm_hw_params_t *params, unsigned int *val)
3865 #else
3866 int snd_pcm_hw_params_get_channels_min(const snd_pcm_hw_params_t *params, unsigned int *val)
3867 #endif
3869 return snd_pcm_hw_param_get_min(params, SND_PCM_HW_PARAM_CHANNELS, val, NULL);
3873 * \brief Extract maximum channels count from a configuration space
3874 * \param params Configuration space
3875 * \param val maximum channels count
3876 * \return 0 otherwise a negative error code
3878 #ifndef DOXYGEN
3879 int INTERNAL(snd_pcm_hw_params_get_channels_max)(const snd_pcm_hw_params_t *params, unsigned int *val)
3880 #else
3881 int snd_pcm_hw_params_get_channels_max(const snd_pcm_hw_params_t *params, unsigned int *val)
3882 #endif
3884 return snd_pcm_hw_param_get_max(params, SND_PCM_HW_PARAM_CHANNELS, val, NULL);
3888 * \brief Verify if a channels count is available inside a configuration space for a PCM
3889 * \param pcm PCM handle
3890 * \param params Configuration space
3891 * \param val channels count
3892 * \return 0 if available a negative error code otherwise
3894 int snd_pcm_hw_params_test_channels(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val)
3896 return snd_pcm_hw_param_set(pcm, params, SND_TEST, SND_PCM_HW_PARAM_CHANNELS, val, 0);
3900 * \brief Restrict a configuration space to contain only one channels count
3901 * \param pcm PCM handle
3902 * \param params Configuration space
3903 * \param val channels count
3904 * \return 0 otherwise a negative error code if configuration space would become empty
3906 int snd_pcm_hw_params_set_channels(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val)
3908 return snd_pcm_hw_param_set(pcm, params, SND_TRY, SND_PCM_HW_PARAM_CHANNELS, val, 0);
3912 * \brief Restrict a configuration space with a minimum channels count
3913 * \param pcm PCM handle
3914 * \param params Configuration space
3915 * \param val minimum channels count (on return filled with actual minimum)
3916 * \return 0 otherwise a negative error code if configuration space would become empty
3918 int snd_pcm_hw_params_set_channels_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val)
3920 return snd_pcm_hw_param_set_min(pcm, params, SND_TRY, SND_PCM_HW_PARAM_CHANNELS, val, NULL);
3924 * \brief Restrict a configuration space with a maximum channels count
3925 * \param pcm PCM handle
3926 * \param params Configuration space
3927 * \param val maximum channels count (on return filled with actual maximum)
3928 * \return 0 otherwise a negative error code if configuration space would become empty
3930 int snd_pcm_hw_params_set_channels_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val)
3932 return snd_pcm_hw_param_set_max(pcm, params, SND_TRY, SND_PCM_HW_PARAM_CHANNELS, val, NULL);
3936 * \brief Restrict a configuration space to have channels counts in a given range
3937 * \param pcm PCM handle
3938 * \param params Configuration space
3939 * \param min minimum channels count (on return filled with actual minimum)
3940 * \param max maximum channels count (on return filled with actual maximum)
3941 * \return 0 otherwise a negative error code if configuration space would become empty
3943 int snd_pcm_hw_params_set_channels_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *min, unsigned int *max)
3945 return snd_pcm_hw_param_set_minmax(pcm, params, SND_TRY, SND_PCM_HW_PARAM_CHANNELS, min, NULL, max, NULL);
3949 * \brief Restrict a configuration space to have channels count nearest to a target
3950 * \param pcm PCM handle
3951 * \param params Configuration space
3952 * \param val target channels count, returned chosen channels count
3953 * \return 0 otherwise a negative error code if configuration space is empty
3955 #ifndef DOXYGEN
3956 int INTERNAL(snd_pcm_hw_params_set_channels_near)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val)
3957 #else
3958 int snd_pcm_hw_params_set_channels_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val)
3959 #endif
3961 return snd_pcm_hw_param_set_near(pcm, params, SND_PCM_HW_PARAM_CHANNELS, val, NULL);
3965 * \brief Restrict a configuration space to contain only its minimum channels count
3966 * \param pcm PCM handle
3967 * \param params Configuration space
3968 * \param val minimum channels count
3969 * \return 0 otherwise a negative error code
3971 #ifndef DOXYGEN
3972 int INTERNAL(snd_pcm_hw_params_set_channels_first)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val)
3973 #else
3974 int snd_pcm_hw_params_set_channels_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val)
3975 #endif
3977 return snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_CHANNELS, val, NULL);
3981 * \brief Restrict a configuration space to contain only its maximum channels count
3982 * \param pcm PCM handle
3983 * \param params Configuration space
3984 * \param val maximum channels count
3985 * \return 0 otherwise a negative error code
3987 #ifndef DOXYGEN
3988 int INTERNAL(snd_pcm_hw_params_set_channels_last)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val)
3989 #else
3990 int snd_pcm_hw_params_set_channels_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val)
3991 #endif
3993 return snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_CHANNELS, val, NULL);
3998 * \brief Extract rate from a configuration space
3999 * \param params Configuration space
4000 * \param val Returned approximate rate
4001 * \param dir Sub unit direction
4002 * \return 0 otherwise a negative error code if the configuration space does not contain a single value
4004 * Actual exact value is <,=,> the approximate one following dir (-1, 0, 1)
4006 #ifndef DOXYGEN
4007 int INTERNAL(snd_pcm_hw_params_get_rate)(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4008 #else
4009 int snd_pcm_hw_params_get_rate(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4010 #endif
4012 return snd_pcm_hw_param_get(params, SND_PCM_HW_PARAM_RATE, val, dir);
4016 * \brief Extract minimum rate from a configuration space
4017 * \param params Configuration space
4018 * \param val Returned approximate minimum rate
4019 * \param dir Sub unit direction
4020 * \return 0 otherwise a negative error code
4022 * Exact value is <,=,> the returned one following dir (-1,0,1)
4024 #ifndef DOXYGEN
4025 int INTERNAL(snd_pcm_hw_params_get_rate_min)(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4026 #else
4027 int snd_pcm_hw_params_get_rate_min(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4028 #endif
4030 return snd_pcm_hw_param_get_min(params, SND_PCM_HW_PARAM_RATE, val, dir);
4034 * \brief Extract maximum rate from a configuration space
4035 * \param params Configuration space
4036 * \param val Returned approximate maximum rate
4037 * \param dir Sub unit direction
4038 * \return 0 otherwise a negative error code
4040 * Exact value is <,=,> the returned one following dir (-1,0,1)
4042 #ifndef DOXYGEN
4043 int INTERNAL(snd_pcm_hw_params_get_rate_max)(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4044 #else
4045 int snd_pcm_hw_params_get_rate_max(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4046 #endif
4048 return snd_pcm_hw_param_get_max(params, SND_PCM_HW_PARAM_RATE, val, dir);
4052 * \brief Verify if a rate is available inside a configuration space for a PCM
4053 * \param pcm PCM handle
4054 * \param params Configuration space
4055 * \param val approximate rate
4056 * \param dir Sub unit direction
4057 * \return 0 if available a negative error code otherwise
4059 * Wanted exact value is <,=,> val following dir (-1,0,1)
4061 int snd_pcm_hw_params_test_rate(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir)
4063 return snd_pcm_hw_param_set(pcm, params, SND_TEST, SND_PCM_HW_PARAM_RATE, val, dir);
4067 * \brief Restrict a configuration space to contain only one rate
4068 * \param pcm PCM handle
4069 * \param params Configuration space
4070 * \param val approximate rate
4071 * \param dir Sub unit direction
4072 * \return 0 otherwise a negative error code if configuration space would become empty
4074 * Wanted exact value is <,=,> val following dir (-1,0,1)
4076 int snd_pcm_hw_params_set_rate(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir)
4078 return snd_pcm_hw_param_set(pcm, params, SND_TRY, SND_PCM_HW_PARAM_RATE, val, dir);
4082 * \brief Restrict a configuration space with a minimum rate
4083 * \param pcm PCM handle
4084 * \param params Configuration space
4085 * \param val approximate minimum rate (on return filled with actual minimum)
4086 * \param dir Sub unit direction (on return filled with actual direction)
4087 * \return 0 otherwise a negative error code if configuration space would become empty
4089 * Wanted/actual exact minimum is <,=,> val following dir (-1,0,1)
4091 int snd_pcm_hw_params_set_rate_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4093 return snd_pcm_hw_param_set_min(pcm, params, SND_TRY, SND_PCM_HW_PARAM_RATE, val, dir);
4097 * \brief Restrict a configuration space with a maximum rate
4098 * \param pcm PCM handle
4099 * \param params Configuration space
4100 * \param val approximate maximum rate (on return filled with actual maximum)
4101 * \param dir Sub unit direction (on return filled with actual direction)
4102 * \return 0 otherwise a negative error code if configuration space would become empty
4104 * Wanted/actual exact maximum is <,=,> val following dir (-1,0,1)
4106 int snd_pcm_hw_params_set_rate_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4108 return snd_pcm_hw_param_set_max(pcm, params, SND_TRY, SND_PCM_HW_PARAM_RATE, val, dir);
4112 * \brief Restrict a configuration space to have rates in a given range
4113 * \param pcm PCM handle
4114 * \param params Configuration space
4115 * \param min approximate minimum rate (on return filled with actual minimum)
4116 * \param mindir Sub unit direction for minimum (on return filled with actual direction)
4117 * \param max approximate maximum rate (on return filled with actual maximum)
4118 * \param maxdir Sub unit direction for maximum (on return filled with actual direction)
4119 * \return 0 otherwise a negative error code if configuration space would become empty
4121 * Wanted/actual exact min/max is <,=,> val following dir (-1,0,1)
4123 int snd_pcm_hw_params_set_rate_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *min, int *mindir, unsigned int *max, int *maxdir)
4125 return snd_pcm_hw_param_set_minmax(pcm, params, SND_TRY, SND_PCM_HW_PARAM_RATE, min, mindir, max, maxdir);
4129 * \brief Restrict a configuration space to have rate nearest to a target
4130 * \param pcm PCM handle
4131 * \param params Configuration space
4132 * \param val approximate target rate / returned approximate set rate
4133 * \param dir Sub unit direction
4134 * \return 0 otherwise a negative error code if configuration space is empty
4136 * target/chosen exact value is <,=,> val following dir (-1,0,1)
4138 #ifndef DOXYGEN
4139 int INTERNAL(snd_pcm_hw_params_set_rate_near)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4140 #else
4141 int snd_pcm_hw_params_set_rate_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4142 #endif
4144 return snd_pcm_hw_param_set_near(pcm, params, SND_PCM_HW_PARAM_RATE, val, dir);
4148 * \brief Restrict a configuration space to contain only its minimum rate
4149 * \param pcm PCM handle
4150 * \param params Configuration space
4151 * \param val Returned minimum approximate rate
4152 * \param dir Sub unit direction
4153 * \return 0 otherwise a negative error code
4155 * Actual exact value is <,=,> the approximate one following dir (-1, 0, 1)
4157 #ifndef DOXYGEN
4158 int INTERNAL(snd_pcm_hw_params_set_rate_first)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4159 #else
4160 int snd_pcm_hw_params_set_rate_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4161 #endif
4163 return snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_RATE, val, dir);
4167 * \brief Restrict a configuration space to contain only its maximum rate
4168 * \param pcm PCM handle
4169 * \param params Configuration space
4170 * \param val Returned maximum approximate rate
4171 * \param dir Sub unit direction
4172 * \return 0 otherwise a negative error code
4174 * Actual exact value is <,=,> the approximate one following dir (-1, 0, 1)
4176 #ifndef DOXYGEN
4177 int INTERNAL(snd_pcm_hw_params_set_rate_last)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4178 #else
4179 int snd_pcm_hw_params_set_rate_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4180 #endif
4182 return snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_RATE, val, dir);
4186 * \brief Restrict a configuration space to contain only real hardware rates
4187 * \param pcm PCM handle
4188 * \param params Configuration space
4189 * \param val 0 = disable, 1 = enable (default) rate resampling
4190 * \return 0 otherwise a negative error code
4192 int snd_pcm_hw_params_set_rate_resample(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val)
4194 assert(pcm && params);
4195 if (!val)
4196 params->flags |= SND_PCM_HW_PARAMS_NORESAMPLE;
4197 else
4198 params->flags &= ~SND_PCM_HW_PARAMS_NORESAMPLE;
4199 params->rmask = ~0;
4200 return snd_pcm_hw_refine(pcm, params);
4204 * \brief Extract resample state from a configuration space
4205 * \param pcm PCM handle
4206 * \param params Configuration space
4207 * \param val 0 = disable, 1 = enable rate resampling
4208 * \return 0 otherwise a negative error code
4210 int snd_pcm_hw_params_get_rate_resample(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val)
4212 assert(pcm && params && val);
4213 *val = params->flags & SND_PCM_HW_PARAMS_NORESAMPLE ? 0 : 1;
4214 return 0;
4218 * \brief Restrict a configuration space to allow the buffer to be accessible from outside
4219 * \param pcm PCM handle
4220 * \param params Configuration space
4221 * \param val 0 = disable, 1 = enable (default) exporting buffer
4222 * \return 0 otherwise a negative error code
4224 int snd_pcm_hw_params_set_export_buffer(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val)
4226 assert(pcm && params);
4227 if (val)
4228 params->flags |= SND_PCM_HW_PARAMS_EXPORT_BUFFER;
4229 else
4230 params->flags &= ~SND_PCM_HW_PARAMS_EXPORT_BUFFER;
4231 params->rmask = ~0;
4232 return snd_pcm_hw_refine(pcm, params);
4236 * \brief Extract buffer accessibility from a configuration space
4237 * \param pcm PCM handle
4238 * \param params Configuration space
4239 * \param val 0 = disable, 1 = enable exporting buffer
4240 * \return 0 otherwise a negative error code
4242 int snd_pcm_hw_params_get_export_buffer(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val)
4244 assert(pcm && params && val);
4245 *val = params->flags & SND_PCM_HW_PARAMS_EXPORT_BUFFER ? 1 : 0;
4246 return 0;
4250 * \brief Restrict a configuration space to settings without period wakeups
4251 * \param pcm PCM handle
4252 * \param params Configuration space
4253 * \param val 0 = disable, 1 = enable (default) period wakeup
4254 * \return Zero on success, otherwise a negative error code.
4256 * This function must be called only on devices where non-blocking mode is
4257 * enabled.
4259 * To check whether the hardware does support disabling period wakeups, call
4260 * #snd_pcm_hw_params_can_disable_period_wakeup(). If the hardware does not
4261 * support this mode, standard period wakeups will be generated.
4263 * Even with disabled period wakeups, the period size/time/count parameters
4264 * are valid; it is suggested to use #snd_pcm_hw_params_set_period_size_last().
4266 * When period wakeups are disabled, the application must not use any functions
4267 * that could block on this device. The use of poll should be limited to error
4268 * cases. The application needs to use an external event or a timer to
4269 * check the state of the ring buffer and refill it apropriately.
4271 int snd_pcm_hw_params_set_period_wakeup(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val)
4273 assert(pcm && params);
4275 if (!val) {
4276 if (!(pcm->mode & SND_PCM_NONBLOCK))
4277 return -EINVAL;
4278 params->flags |= SND_PCM_HW_PARAMS_NO_PERIOD_WAKEUP;
4279 } else
4280 params->flags &= ~SND_PCM_HW_PARAMS_NO_PERIOD_WAKEUP;
4281 params->rmask = ~0;
4283 return snd_pcm_hw_refine(pcm, params);
4287 * \brief Extract period wakeup flag from a configuration space
4288 * \param pcm PCM handle
4289 * \param params Configuration space
4290 * \param val 0 = disabled, 1 = enabled period wakeups
4291 * \return Zero on success, otherwise a negative error code.
4293 int snd_pcm_hw_params_get_period_wakeup(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val)
4295 assert(pcm && params && val);
4296 *val = params->flags & SND_PCM_HW_PARAMS_NO_PERIOD_WAKEUP ? 0 : 1;
4297 return 0;
4301 * \brief Extract period time from a configuration space
4302 * \param params Configuration space
4303 * \param val Returned approximate period duration in us
4304 * \param dir Sub unit direction
4305 * \return 0 otherwise a negative error code if the configuration space does not contain a single value
4307 * Actual exact value is <,=,> the approximate one following dir (-1, 0, 1)
4309 #ifndef DOXYGEN
4310 int INTERNAL(snd_pcm_hw_params_get_period_time)(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4311 #else
4312 int snd_pcm_hw_params_get_period_time(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4313 #endif
4315 return snd_pcm_hw_param_get(params, SND_PCM_HW_PARAM_PERIOD_TIME, val, dir);
4319 * \brief Extract minimum period time from a configuration space
4320 * \param params Configuration space
4321 * \param val approximate minimum period duration in us
4322 * \param dir Sub unit direction
4323 * \return 0 otherwise a negative error code
4325 * Exact value is <,=,> the returned one following dir (-1,0,1)
4327 #ifndef DOXYGEN
4328 int INTERNAL(snd_pcm_hw_params_get_period_time_min)(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4329 #else
4330 int snd_pcm_hw_params_get_period_time_min(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4331 #endif
4333 return snd_pcm_hw_param_get_min(params, SND_PCM_HW_PARAM_PERIOD_TIME, val, dir);
4337 * \brief Extract maximum period time from a configuration space
4338 * \param params Configuration space
4339 * \param val approximate maximum period duration in us
4340 * \param dir Sub unit direction
4341 * \return 0 otherwise a negative error code
4343 * Exact value is <,=,> the returned one following dir (-1,0,1)
4345 #ifndef DOXYGEN
4346 int INTERNAL(snd_pcm_hw_params_get_period_time_max)(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4347 #else
4348 int snd_pcm_hw_params_get_period_time_max(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4349 #endif
4351 return snd_pcm_hw_param_get_max(params, SND_PCM_HW_PARAM_PERIOD_TIME, val, dir);
4355 * \brief Verify if a period time is available inside a configuration space for a PCM
4356 * \param pcm PCM handle
4357 * \param params Configuration space
4358 * \param val approximate period duration in us
4359 * \param dir Sub unit direction
4360 * \return 0 if available a negative error code otherwise
4362 * Wanted exact value is <,=,> val following dir (-1,0,1)
4364 int snd_pcm_hw_params_test_period_time(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir)
4366 return snd_pcm_hw_param_set(pcm, params, SND_TEST, SND_PCM_HW_PARAM_PERIOD_TIME, val, dir);
4370 * \brief Restrict a configuration space to contain only one period time
4371 * \param pcm PCM handle
4372 * \param params Configuration space
4373 * \param val approximate period duration in us
4374 * \param dir Sub unit direction
4375 * \return 0 otherwise a negative error code if configuration space would become empty
4377 * Wanted exact value is <,=,> val following dir (-1,0,1)
4379 int snd_pcm_hw_params_set_period_time(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir)
4381 return snd_pcm_hw_param_set(pcm, params, SND_TRY, SND_PCM_HW_PARAM_PERIOD_TIME, val, dir);
4386 * \brief Restrict a configuration space with a minimum period time
4387 * \param pcm PCM handle
4388 * \param params Configuration space
4389 * \param val approximate minimum period duration in us (on return filled with actual minimum)
4390 * \param dir Sub unit direction (on return filled with actual direction)
4391 * \return 0 otherwise a negative error code if configuration space would become empty
4393 * Wanted/actual exact minimum is <,=,> val following dir (-1,0,1)
4395 int snd_pcm_hw_params_set_period_time_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4397 return snd_pcm_hw_param_set_min(pcm, params, SND_TRY, SND_PCM_HW_PARAM_PERIOD_TIME, val, dir);
4401 * \brief Restrict a configuration space with a maximum period time
4402 * \param pcm PCM handle
4403 * \param params Configuration space
4404 * \param val approximate maximum period duration in us (on return filled with actual maximum)
4405 * \param dir Sub unit direction (on return filled with actual direction)
4406 * \return 0 otherwise a negative error code if configuration space would become empty
4408 * Wanted/actual exact maximum is <,=,> val following dir (-1,0,1)
4410 int snd_pcm_hw_params_set_period_time_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4412 return snd_pcm_hw_param_set_max(pcm, params, SND_TRY, SND_PCM_HW_PARAM_PERIOD_TIME, val, dir);
4416 * \brief Restrict a configuration space to have period times in a given range
4417 * \param pcm PCM handle
4418 * \param params Configuration space
4419 * \param min approximate minimum period duration in us (on return filled with actual minimum)
4420 * \param mindir Sub unit direction for minimum (on return filled with actual direction)
4421 * \param max approximate maximum period duration in us (on return filled with actual maximum)
4422 * \param maxdir Sub unit direction for maximum (on return filled with actual direction)
4423 * \return 0 otherwise a negative error code if configuration space would become empty
4425 * Wanted/actual exact min/max is <,=,> val following dir (-1,0,1)
4427 int snd_pcm_hw_params_set_period_time_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *min, int *mindir, unsigned int *max, int *maxdir)
4429 return snd_pcm_hw_param_set_minmax(pcm, params, SND_TRY, SND_PCM_HW_PARAM_PERIOD_TIME, min, mindir, max, maxdir);
4433 * \brief Restrict a configuration space to have period time nearest to a target
4434 * \param pcm PCM handle
4435 * \param params Configuration space
4436 * \param val approximate target period duration in us / returned chosen approximate target period duration
4437 * \param dir Sub unit direction
4438 * \return 0 otherwise a negative error code if configuration space is empty
4440 * target/chosen exact value is <,=,> val following dir (-1,0,1)
4442 #ifndef DOXYGEN
4443 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)
4444 #else
4445 int snd_pcm_hw_params_set_period_time_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4446 #endif
4448 return snd_pcm_hw_param_set_near(pcm, params, SND_PCM_HW_PARAM_PERIOD_TIME, val, dir);
4452 * \brief Restrict a configuration space to contain only its minimum period time
4453 * \param pcm PCM handle
4454 * \param params Configuration space
4455 * \param val Returned approximate period duration in us
4456 * \param dir Sub unit direction
4457 * \return 0 otherwise a negative error code
4459 * Actual exact value is <,=,> the approximate one following dir (-1, 0, 1)
4461 #ifndef DOXYGEN
4462 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)
4463 #else
4464 int snd_pcm_hw_params_set_period_time_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4465 #endif
4467 return snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_PERIOD_TIME, val, dir);
4471 * \brief Restrict a configuration space to contain only its maximum period time
4472 * \param pcm PCM handle
4473 * \param params Configuration space
4474 * \param val Returned maximum approximate period time
4475 * \param dir Sub unit direction
4476 * \return approximate period duration in us
4478 #ifndef DOXYGEN
4479 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)
4480 #else
4481 int snd_pcm_hw_params_set_period_time_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4482 #endif
4484 return snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_PERIOD_TIME, val, dir);
4489 * \brief Extract period size from a configuration space
4490 * \param params Configuration space
4491 * \param val Returned approximate period size in frames
4492 * \param dir Sub unit direction
4493 * \return 0 otherwise a negative error code if the configuration space does not contain a single value
4495 * Actual exact value is <,=,> the approximate one following dir (-1, 0, 1)
4497 #ifndef DOXYGEN
4498 int INTERNAL(snd_pcm_hw_params_get_period_size)(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir)
4499 #else
4500 int snd_pcm_hw_params_get_period_size(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir)
4501 #endif
4503 unsigned int _val;
4504 int err = snd_pcm_hw_param_get(params, SND_PCM_HW_PARAM_PERIOD_SIZE, &_val, dir);
4505 if (err >= 0)
4506 *val = _val;
4507 return err;
4511 * \brief Extract minimum period size from a configuration space
4512 * \param params Configuration space
4513 * \param val approximate minimum period size in frames
4514 * \param dir Sub unit direction
4515 * \return 0 otherwise a negative error code
4517 * Exact value is <,=,> the returned one following dir (-1,0,1)
4519 #ifndef DOXYGEN
4520 int INTERNAL(snd_pcm_hw_params_get_period_size_min)(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir)
4521 #else
4522 int snd_pcm_hw_params_get_period_size_min(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir)
4523 #endif
4525 unsigned int _val = *val;
4526 int err = snd_pcm_hw_param_get_min(params, SND_PCM_HW_PARAM_PERIOD_SIZE, &_val, dir);
4527 if (err >= 0)
4528 *val = _val;
4529 return err;
4533 * \brief Extract maximum period size from a configuration space
4534 * \param params Configuration space
4535 * \param val approximate minimum period size in frames
4536 * \param dir Sub unit direction
4537 * \return 0 otherwise a negative error code
4539 * Exact value is <,=,> the returned one following dir (-1,0,1)
4541 #ifndef DOXYGEN
4542 int INTERNAL(snd_pcm_hw_params_get_period_size_max)(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir)
4543 #else
4544 int snd_pcm_hw_params_get_period_size_max(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir)
4545 #endif
4547 unsigned int _val = *val;
4548 int err = snd_pcm_hw_param_get_max(params, SND_PCM_HW_PARAM_PERIOD_SIZE, &_val, dir);
4549 if (err >= 0)
4550 *val = _val;
4551 return err;
4555 * \brief Verify if a period size is available inside a configuration space for a PCM
4556 * \param pcm PCM handle
4557 * \param params Configuration space
4558 * \param val approximate period size in frames
4559 * \param dir Sub unit direction
4560 * \return 0 if available a negative error code otherwise
4562 * Wanted exact value is <,=,> val following dir (-1,0,1)
4564 int snd_pcm_hw_params_test_period_size(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val, int dir)
4566 return snd_pcm_hw_param_set(pcm, params, SND_TEST, SND_PCM_HW_PARAM_PERIOD_SIZE, val, dir);
4570 * \brief Restrict a configuration space to contain only one period size
4571 * \param pcm PCM handle
4572 * \param params Configuration space
4573 * \param val approximate period size in frames
4574 * \param dir Sub unit direction
4575 * \return 0 otherwise a negative error code if configuration space would become empty
4577 * Wanted exact value is <,=,> val following dir (-1,0,1)
4579 int snd_pcm_hw_params_set_period_size(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val, int dir)
4581 return snd_pcm_hw_param_set(pcm, params, SND_TRY, SND_PCM_HW_PARAM_PERIOD_SIZE, val, dir);
4585 * \brief Restrict a configuration space with a minimum period size
4586 * \param pcm PCM handle
4587 * \param params Configuration space
4588 * \param val approximate minimum period size in frames (on return filled with actual minimum)
4589 * \param dir Sub unit direction (on return filled with actual direction)
4590 * \return 0 otherwise a negative error code if configuration space would become empty
4592 * Wanted/actual exact minimum is <,=,> val following dir (-1,0,1)
4594 int snd_pcm_hw_params_set_period_size_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir)
4596 unsigned int _val = *val;
4597 int err = snd_pcm_hw_param_set_min(pcm, params, SND_TRY, SND_PCM_HW_PARAM_PERIOD_SIZE, &_val, dir);
4598 if (err >= 0)
4599 *val = _val;
4600 return err;
4604 * \brief Restrict a configuration space with a maximum period size
4605 * \param pcm PCM handle
4606 * \param params Configuration space
4607 * \param val approximate maximum period size in frames (on return filled with actual maximum)
4608 * \param dir Sub unit direction (on return filled with actual direction)
4609 * \return 0 otherwise a negative error code if configuration space would become empty
4611 * Wanted/actual exact minimum is <,=,> val following dir (-1,0,1)
4613 int snd_pcm_hw_params_set_period_size_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir)
4615 unsigned int _val = *val;
4616 int err = snd_pcm_hw_param_set_max(pcm, params, SND_TRY, SND_PCM_HW_PARAM_PERIOD_SIZE, &_val, dir);
4617 if (err >= 0)
4618 *val = _val;
4619 return err;
4623 * \brief Restrict a configuration space to have period sizes in a given range
4624 * \param pcm PCM handle
4625 * \param params Configuration space
4626 * \param min approximate minimum period size in frames (on return filled with actual minimum)
4627 * \param mindir Sub unit direction for minimum (on return filled with actual direction)
4628 * \param max approximate maximum period size in frames (on return filled with actual maximum)
4629 * \param maxdir Sub unit direction for maximum (on return filled with actual direction)
4630 * \return 0 otherwise a negative error code if configuration space would become empty
4632 * Wanted/actual exact min/max is <,=,> val following dir (-1,0,1)
4634 int snd_pcm_hw_params_set_period_size_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *min, int *mindir, snd_pcm_uframes_t *max, int *maxdir)
4636 unsigned int _min = *min;
4637 unsigned int _max = *max;
4638 int err = snd_pcm_hw_param_set_minmax(pcm, params, SND_TRY, SND_PCM_HW_PARAM_PERIOD_SIZE, &_min, mindir, &_max, maxdir);
4639 *min = _min;
4640 *max = _max;
4641 return err;
4645 * \brief Restrict a configuration space to have period size nearest to a target
4646 * \param pcm PCM handle
4647 * \param params Configuration space
4648 * \param val approximate target period size in frames / returned chosen approximate target period size
4649 * \param dir Sub unit direction
4650 * \return 0 otherwise a negative error code if configuration space is empty
4652 * target/chosen exact value is <,=,> val following dir (-1,0,1)
4654 #ifndef DOXYGEN
4655 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)
4656 #else
4657 int snd_pcm_hw_params_set_period_size_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir)
4658 #endif
4660 unsigned int _val = *val;
4661 int err = snd_pcm_hw_param_set_near(pcm, params, SND_PCM_HW_PARAM_PERIOD_SIZE, &_val, dir);
4662 if (err >= 0)
4663 *val = _val;
4664 return err;
4668 * \brief Restrict a configuration space to contain only its minimum period size
4669 * \param pcm PCM handle
4670 * \param params Configuration space
4671 * \param val Returned maximum approximate period size in frames
4672 * \param dir Sub unit direction
4673 * \return 0 otherwise a negative error code
4675 * Actual exact value is <,=,> the approximate one following dir (-1, 0, 1)
4677 #ifndef DOXYGEN
4678 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)
4679 #else
4680 int snd_pcm_hw_params_set_period_size_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir)
4681 #endif
4683 unsigned int _val;
4684 int err = snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_PERIOD_SIZE, &_val, dir);
4685 if (err >= 0)
4686 *val = _val;
4687 return err;
4691 * \brief Restrict a configuration space to contain only its maximum period size
4692 * \param pcm PCM handle
4693 * \param params Configuration space
4694 * \param val Returned maximum approximate period size in frames
4695 * \param dir Sub unit direction
4696 * \return 0 otherwise a negative error code
4698 * Actual exact value is <,=,> the approximate one following dir (-1, 0, 1)
4700 #ifndef DOXYGEN
4701 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)
4702 #else
4703 int snd_pcm_hw_params_set_period_size_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir)
4704 #endif
4706 unsigned int _val;
4707 int err = snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_PERIOD_SIZE, &_val, dir);
4708 if (err >= 0)
4709 *val = _val;
4710 return err;
4714 * \brief Restrict a configuration space to contain only integer period sizes
4715 * \param pcm PCM handle
4716 * \param params Configuration space
4717 * \return 0 otherwise a negative error code if configuration space would become empty
4719 int snd_pcm_hw_params_set_period_size_integer(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
4721 return snd_pcm_hw_param_set_integer(pcm, params, SND_TRY, SND_PCM_HW_PARAM_PERIOD_SIZE);
4726 * \brief Extract periods from a configuration space
4727 * \param params Configuration space
4728 * \param val approximate periods per buffer
4729 * \param dir Sub unit direction
4730 * \return 0 otherwise a negative error code if the configuration space does not contain a single value
4732 * Actual exact value is <,=,> the approximate one following dir (-1, 0, 1)
4734 #ifndef DOXYGEN
4735 int INTERNAL(snd_pcm_hw_params_get_periods)(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4736 #else
4737 int snd_pcm_hw_params_get_periods(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4738 #endif
4740 return snd_pcm_hw_param_get(params, SND_PCM_HW_PARAM_PERIODS, val, dir);
4744 * \brief Extract minimum periods count from a configuration space
4745 * \param params Configuration space
4746 * \param val approximate minimum periods per buffer
4747 * \param dir Sub unit direction
4748 * \return 0 otherwise a negative error code
4750 * Exact value is <,=,> the returned one following dir (-1,0,1)
4752 #ifndef DOXYGEN
4753 int INTERNAL(snd_pcm_hw_params_get_periods_min)(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4754 #else
4755 int snd_pcm_hw_params_get_periods_min(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4756 #endif
4758 return snd_pcm_hw_param_get_min(params, SND_PCM_HW_PARAM_PERIODS, val, dir);
4762 * \brief Extract maximum periods count from a configuration space
4763 * \param params Configuration space
4764 * \param val approximate maximum periods per buffer
4765 * \param dir Sub unit direction
4766 * \return 0 otherwise a negative error code
4768 * Exact value is <,=,> the returned one following dir (-1,0,1)
4770 #ifndef DOXYGEN
4771 int INTERNAL(snd_pcm_hw_params_get_periods_max)(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4772 #else
4773 int snd_pcm_hw_params_get_periods_max(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4774 #endif
4776 return snd_pcm_hw_param_get_max(params, SND_PCM_HW_PARAM_PERIODS, val, dir);
4780 * \brief Verify if a periods count is available inside a configuration space for a PCM
4781 * \param pcm PCM handle
4782 * \param params Configuration space
4783 * \param val approximate periods per buffer
4784 * \param dir Sub unit direction
4785 * \return 0 if available a negative error code otherwise
4787 * Wanted exact value is <,=,> val following dir (-1,0,1)
4789 int snd_pcm_hw_params_test_periods(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir)
4791 return snd_pcm_hw_param_set(pcm, params, SND_TEST, SND_PCM_HW_PARAM_PERIODS, val, dir);
4795 * \brief Restrict a configuration space to contain only one periods count
4796 * \param pcm PCM handle
4797 * \param params Configuration space
4798 * \param val approximate periods per buffer
4799 * \param dir Sub unit direction
4800 * \return 0 otherwise a negative error code if configuration space would become empty
4802 * Wanted exact value is <,=,> val following dir (-1,0,1)
4804 int snd_pcm_hw_params_set_periods(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir)
4806 return snd_pcm_hw_param_set(pcm, params, SND_TRY, SND_PCM_HW_PARAM_PERIODS, val, dir);
4810 * \brief Restrict a configuration space with a minimum periods count
4811 * \param pcm PCM handle
4812 * \param params Configuration space
4813 * \param val approximate minimum periods per buffer (on return filled with actual minimum)
4814 * \param dir Sub unit direction (on return filled with actual direction)
4815 * \return 0 otherwise a negative error code if configuration space would become empty
4817 * Wanted/actual exact minimum is <,=,> val following dir (-1,0,1)
4819 int snd_pcm_hw_params_set_periods_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4821 return snd_pcm_hw_param_set_min(pcm, params, SND_TRY, SND_PCM_HW_PARAM_PERIODS, val, dir);
4825 * \brief Restrict a configuration space with a maximum periods count
4826 * \param pcm PCM handle
4827 * \param params Configuration space
4828 * \param val approximate maximum periods per buffer (on return filled with actual maximum)
4829 * \param dir Sub unit direction (on return filled with actual direction)
4830 * \return 0 otherwise a negative error code if configuration space would become empty
4832 * Wanted/actual exact maximum is <,=,> val following dir (-1,0,1)
4834 int snd_pcm_hw_params_set_periods_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4836 return snd_pcm_hw_param_set_max(pcm, params, SND_TRY, SND_PCM_HW_PARAM_PERIODS, val, dir);
4840 * \brief Restrict a configuration space to have periods counts in a given range
4841 * \param pcm PCM handle
4842 * \param params Configuration space
4843 * \param min approximate minimum periods per buffer (on return filled with actual minimum)
4844 * \param mindir Sub unit direction for minimum (on return filled with actual direction)
4845 * \param max approximate maximum periods per buffer (on return filled with actual maximum)
4846 * \param maxdir Sub unit direction for maximum (on return filled with actual direction)
4847 * \return 0 otherwise a negative error code if configuration space would become empty
4849 * Wanted/actual exact min/max is <,=,> val following dir (-1,0,1)
4851 int snd_pcm_hw_params_set_periods_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *min, int *mindir, unsigned int *max, int *maxdir)
4853 return snd_pcm_hw_param_set_minmax(pcm, params, SND_TRY, SND_PCM_HW_PARAM_PERIODS, min, mindir, max, maxdir);
4857 * \brief Restrict a configuration space to have periods count nearest to a target
4858 * \param pcm PCM handle
4859 * \param params Configuration space
4860 * \param val approximate target periods per buffer / returned chosen approximate target periods per buffer
4861 * \param dir Sub unit direction
4862 * \return 0 otherwise a negative error code if configuration space is empty
4864 * target/chosen exact value is <,=,> val following dir (-1,0,1)
4866 #ifndef DOXYGEN
4867 int INTERNAL(snd_pcm_hw_params_set_periods_near)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4868 #else
4869 int snd_pcm_hw_params_set_periods_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4870 #endif
4872 return snd_pcm_hw_param_set_near(pcm, params, SND_PCM_HW_PARAM_PERIODS, val, dir);
4876 * \brief Restrict a configuration space to contain only its minimum periods count
4877 * \param pcm PCM handle
4878 * \param params Configuration space
4879 * \param val Returned approximate minimum periods per buffer
4880 * \param dir Sub unit direction
4881 * \return 0 otherwise a negative error code
4883 * Actual exact value is <,=,> the approximate one following dir (-1, 0, 1)
4885 #ifndef DOXYGEN
4886 int INTERNAL(snd_pcm_hw_params_set_periods_first)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4887 #else
4888 int snd_pcm_hw_params_set_periods_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4889 #endif
4891 return snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_PERIODS, val, dir);
4895 * \brief Restrict a configuration space to contain only its maximum periods count
4896 * \param pcm PCM handle
4897 * \param params Configuration space
4898 * \param val Returned approximate maximum periods per buffer
4899 * \param dir Sub unit direction
4900 * \return 0 otherwise a negative error code
4902 * Actual exact value is <,=,> the approximate one following dir (-1, 0, 1)
4904 #ifndef DOXYGEN
4905 int INTERNAL(snd_pcm_hw_params_set_periods_last)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4906 #else
4907 int snd_pcm_hw_params_set_periods_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4908 #endif
4910 return snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_PERIODS, val, dir);
4914 * \brief Restrict a configuration space to contain only integer periods counts
4915 * \param pcm PCM handle
4916 * \param params Configuration space
4917 * \return 0 otherwise a negative error code if configuration space would become empty
4919 int snd_pcm_hw_params_set_periods_integer(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
4921 return snd_pcm_hw_param_set_integer(pcm, params, SND_TRY, SND_PCM_HW_PARAM_PERIODS);
4926 * \brief Extract buffer time from a configuration space
4927 * \param params Configuration space
4928 * \param val Returned buffer time in us
4929 * \param dir Sub unit direction
4930 * \return 0 otherwise a negative error code if the configuration space does not contain a single value
4932 * Actual exact value is <,=,> the approximate one following dir (-1, 0, 1)
4934 #ifndef DOXYGEN
4935 int INTERNAL(snd_pcm_hw_params_get_buffer_time)(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4936 #else
4937 int snd_pcm_hw_params_get_buffer_time(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4938 #endif
4940 return snd_pcm_hw_param_get(params, SND_PCM_HW_PARAM_BUFFER_TIME, val, dir);
4944 * \brief Extract minimum buffer time from a configuration space
4945 * \param params Configuration space
4946 * \param val approximate minimum buffer duration in us
4947 * \param dir Sub unit direction
4948 * \return 0 otherwise a negative error code
4950 * Exact value is <,=,> the returned one following dir (-1,0,1)
4952 #ifndef DOXYGEN
4953 int INTERNAL(snd_pcm_hw_params_get_buffer_time_min)(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4954 #else
4955 int snd_pcm_hw_params_get_buffer_time_min(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4956 #endif
4958 return snd_pcm_hw_param_get_min(params, SND_PCM_HW_PARAM_BUFFER_TIME, val, dir);
4962 * \brief Extract maximum buffer time from a configuration space
4963 * \param params Configuration space
4964 * \param val approximate maximum buffer duration in us
4965 * \param dir Sub unit direction
4966 * \return 0 otherwise a negative error code
4968 * Exact value is <,=,> the returned one following dir (-1,0,1)
4970 #ifndef DOXYGEN
4971 int INTERNAL(snd_pcm_hw_params_get_buffer_time_max)(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4972 #else
4973 int snd_pcm_hw_params_get_buffer_time_max(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
4974 #endif
4976 return snd_pcm_hw_param_get_max(params, SND_PCM_HW_PARAM_BUFFER_TIME, val, dir);
4980 * \brief Verify if a buffer time is available inside a configuration space for a PCM
4981 * \param pcm PCM handle
4982 * \param params Configuration space
4983 * \param val approximate buffer duration in us
4984 * \param dir Sub unit direction
4985 * \return 0 if available a negative error code otherwise
4987 * Wanted exact value is <,=,> val following dir (-1,0,1)
4989 int snd_pcm_hw_params_test_buffer_time(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir)
4991 return snd_pcm_hw_param_set(pcm, params, SND_TEST, SND_PCM_HW_PARAM_BUFFER_TIME, val, dir);
4995 * \brief Restrict a configuration space to contain only one buffer time
4996 * \param pcm PCM handle
4997 * \param params Configuration space
4998 * \param val approximate buffer duration in us
4999 * \param dir Sub unit direction
5000 * \return 0 otherwise a negative error code if configuration space would become empty
5002 * Wanted exact value is <,=,> val following dir (-1,0,1)
5004 int snd_pcm_hw_params_set_buffer_time(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir)
5006 return snd_pcm_hw_param_set(pcm, params, SND_TRY, SND_PCM_HW_PARAM_BUFFER_TIME, val, dir);
5010 * \brief Restrict a configuration space with a minimum buffer time
5011 * \param pcm PCM handle
5012 * \param params Configuration space
5013 * \param val approximate minimum buffer duration in us (on return filled with actual minimum)
5014 * \param dir Sub unit direction (on return filled with actual direction)
5015 * \return 0 otherwise a negative error code if configuration space would become empty
5017 * Wanted/actual exact minimum is <,=,> val following dir (-1,0,1)
5019 int snd_pcm_hw_params_set_buffer_time_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
5021 return snd_pcm_hw_param_set_min(pcm, params, SND_TRY, SND_PCM_HW_PARAM_BUFFER_TIME, val, dir);
5025 * \brief Restrict a configuration space with a maximum buffer time
5026 * \param pcm PCM handle
5027 * \param params Configuration space
5028 * \param val approximate maximum buffer duration in us (on return filled with actual maximum)
5029 * \param dir Sub unit direction (on return filled with actual direction)
5030 * \return 0 otherwise a negative error code if configuration space would become empty
5032 * Wanted/actual exact maximum is <,=,> val following dir (-1,0,1)
5034 int snd_pcm_hw_params_set_buffer_time_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
5036 return snd_pcm_hw_param_set_max(pcm, params, SND_TRY, SND_PCM_HW_PARAM_BUFFER_TIME, val, dir);
5040 * \brief Restrict a configuration space to have buffer times in a given range
5041 * \param pcm PCM handle
5042 * \param params Configuration space
5043 * \param min approximate minimum buffer duration in us (on return filled with actual minimum)
5044 * \param mindir Sub unit direction for minimum (on return filled with actual direction)
5045 * \param max approximate maximum buffer duration in us (on return filled with actual maximum)
5046 * \param maxdir Sub unit direction for maximum (on return filled with actual direction)
5047 * \return 0 otherwise a negative error code if configuration space would become empty
5049 * Wanted/actual exact min/max is <,=,> val following dir (-1,0,1)
5051 int snd_pcm_hw_params_set_buffer_time_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *min, int *mindir, unsigned int *max, int *maxdir)
5053 return snd_pcm_hw_param_set_minmax(pcm, params, SND_TRY, SND_PCM_HW_PARAM_BUFFER_TIME, min, mindir, max, maxdir);
5057 * \brief Restrict a configuration space to have buffer time nearest to a target
5058 * \param pcm PCM handle
5059 * \param params Configuration space
5060 * \param val approximate target buffer duration in us / returned chosen approximate target buffer duration
5061 * \param dir Sub unit direction
5062 * \return 0 otherwise a negative error code if configuration space is empty
5064 * target/chosen exact value is <,=,> val following dir (-1,0,1)
5066 #ifndef DOXYGEN
5067 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)
5068 #else
5069 int snd_pcm_hw_params_set_buffer_time_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
5070 #endif
5072 return snd_pcm_hw_param_set_near(pcm, params, SND_PCM_HW_PARAM_BUFFER_TIME, val, dir);
5076 * \brief Restrict a configuration space to contain only its minimum buffer time
5077 * \param pcm PCM handle
5078 * \param params Configuration space
5079 * \param val Returned approximate minimum buffer duration in us
5080 * \param dir Sub unit direction
5081 * \return 0 otherwise a negative error code
5083 * Actual exact value is <,=,> the approximate one following dir (-1, 0, 1)
5085 #ifndef DOXYGEN
5086 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)
5087 #else
5088 int snd_pcm_hw_params_set_buffer_time_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
5089 #endif
5091 return snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_BUFFER_TIME, val, dir);
5095 * \brief Restrict a configuration space to contain only its maximum buffered time
5096 * \param pcm PCM handle
5097 * \param params Configuration space
5098 * \param val Returned approximate maximum buffer duration in us
5099 * \param dir Sub unit direction
5100 * \return 0 otherwise a negative error code
5102 * Actual exact value is <,=,> the approximate one following dir (-1, 0, 1)
5104 #ifndef DOXYGEN
5105 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)
5106 #else
5107 int snd_pcm_hw_params_set_buffer_time_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
5108 #endif
5110 return snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_BUFFER_TIME, val, dir);
5115 * \brief Extract buffer size from a configuration space
5116 * \param params Configuration space
5117 * \param val Returned buffer size in frames
5118 * \return 0 otherwise a negative error code if the configuration space does not contain a single value
5120 #ifndef DOXYGEN
5121 int INTERNAL(snd_pcm_hw_params_get_buffer_size)(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val)
5122 #else
5123 int snd_pcm_hw_params_get_buffer_size(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val)
5124 #endif
5126 unsigned int _val;
5127 int err = snd_pcm_hw_param_get(params, SND_PCM_HW_PARAM_BUFFER_SIZE, &_val, NULL);
5128 if (err >= 0)
5129 *val = _val;
5130 return err;
5134 * \brief Extract minimum buffer size from a configuration space
5135 * \param params Configuration space
5136 * \param val Returned approximate minimum buffer size in frames
5137 * \return 0 otherwise a negative error code
5139 #ifndef DOXYGEN
5140 int INTERNAL(snd_pcm_hw_params_get_buffer_size_min)(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val)
5141 #else
5142 int snd_pcm_hw_params_get_buffer_size_min(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val)
5143 #endif
5145 unsigned int _val;
5146 int err = snd_pcm_hw_param_get_min(params, SND_PCM_HW_PARAM_BUFFER_SIZE, &_val, NULL);
5147 if (err >= 0)
5148 *val = _val;
5149 return err;
5153 * \brief Extract maximum buffer size from a configuration space
5154 * \param params Configuration space
5155 * \param val Returned approximate maximum buffer size in frames
5156 * \return 0 otherwise a negative error code
5158 * Exact value is <,=,> the returned one following dir (-1,0,1)
5160 #ifndef DOXYGEN
5161 int INTERNAL(snd_pcm_hw_params_get_buffer_size_max)(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val)
5162 #else
5163 int snd_pcm_hw_params_get_buffer_size_max(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val)
5164 #endif
5166 unsigned int _val;
5167 int err = snd_pcm_hw_param_get_max(params, SND_PCM_HW_PARAM_BUFFER_SIZE, &_val, NULL);
5168 if (err >= 0)
5169 *val = _val;
5170 return err;
5174 * \brief Verify if a buffer size is available inside a configuration space for a PCM
5175 * \param pcm PCM handle
5176 * \param params Configuration space
5177 * \param val buffer size in frames
5178 * \return 0 if available a negative error code otherwise
5180 * Wanted exact value is <,=,> val following dir (-1,0,1)
5182 int snd_pcm_hw_params_test_buffer_size(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val)
5184 return snd_pcm_hw_param_set(pcm, params, SND_TEST, SND_PCM_HW_PARAM_BUFFER_SIZE, val, 0);
5188 * \brief Restrict a configuration space to contain only one buffer size
5189 * \param pcm PCM handle
5190 * \param params Configuration space
5191 * \param val buffer size in frames
5192 * \return 0 otherwise a negative error code if configuration space would become empty
5194 * Wanted exact value is <,=,> val following dir (-1,0,1)
5196 int snd_pcm_hw_params_set_buffer_size(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val)
5198 return snd_pcm_hw_param_set(pcm, params, SND_TRY, SND_PCM_HW_PARAM_BUFFER_SIZE, val, 0);
5202 * \brief Restrict a configuration space with a minimum buffer size
5203 * \param pcm PCM handle
5204 * \param params Configuration space
5205 * \param val approximate minimum buffer size in frames (on return filled with actual minimum)
5206 * \return 0 otherwise a negative error code if configuration space would become empty
5208 int snd_pcm_hw_params_set_buffer_size_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val)
5210 unsigned int _val = *val;
5211 int err = snd_pcm_hw_param_set_min(pcm, params, SND_TRY, SND_PCM_HW_PARAM_BUFFER_SIZE, &_val, NULL);
5212 if (err >= 0)
5213 *val = _val;
5214 return err;
5218 * \brief Restrict a configuration space with a maximum buffer size
5219 * \param pcm PCM handle
5220 * \param params Configuration space
5221 * \param val approximate maximum buffer size in frames (on return filled with actual maximum)
5222 * \return 0 otherwise a negative error code if configuration space would become empty
5224 int snd_pcm_hw_params_set_buffer_size_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val)
5226 unsigned int _val = *val;
5227 int err = snd_pcm_hw_param_set_max(pcm, params, SND_TRY, SND_PCM_HW_PARAM_BUFFER_SIZE, &_val, NULL);
5228 if (err >= 0)
5229 *val = _val;
5230 return err;
5234 * \brief Restrict a configuration space to have buffer sizes in a given range
5235 * \param pcm PCM handle
5236 * \param params Configuration space
5237 * \param min approximate minimum buffer size in frames (on return filled with actual minimum)
5238 * \param max approximate maximum buffer size in frames (on return filled with actual maximum)
5239 * \return 0 otherwise a negative error code if configuration space would become empty
5241 int snd_pcm_hw_params_set_buffer_size_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *min, snd_pcm_uframes_t *max)
5243 unsigned int _min = *min;
5244 unsigned int _max = *max;
5245 int err = snd_pcm_hw_param_set_minmax(pcm, params, SND_TRY, SND_PCM_HW_PARAM_BUFFER_SIZE, &_min, NULL, &_max, NULL);
5246 *min = _min;
5247 *max = _max;
5248 return err;
5252 * \brief Restrict a configuration space to have buffer size nearest to a target
5253 * \param pcm PCM handle
5254 * \param params Configuration space
5255 * \param val approximate target buffer size in frames / returned chosen approximate target buffer size in frames
5256 * \return 0 otherwise a negative error code if configuration space is empty
5258 #ifndef DOXYGEN
5259 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)
5260 #else
5261 int snd_pcm_hw_params_set_buffer_size_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val)
5262 #endif
5264 unsigned int _val = *val;
5265 int err = snd_pcm_hw_param_set_near(pcm, params, SND_PCM_HW_PARAM_BUFFER_SIZE, &_val, NULL);
5266 if (err >= 0)
5267 *val = _val;
5268 return err;
5272 * \brief Restrict a configuration space to contain only its minimum buffer size
5273 * \param pcm PCM handle
5274 * \param params Configuration space
5275 * \param val Returned minimum buffer size in frames
5276 * \return buffer size in frames
5278 #ifndef DOXYGEN
5279 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)
5280 #else
5281 int snd_pcm_hw_params_set_buffer_size_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val)
5282 #endif
5284 unsigned int _val;
5285 int err = snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_BUFFER_SIZE, &_val, NULL);
5286 if (err >= 0)
5287 *val = _val;
5288 return err;
5292 * \brief Restrict a configuration space to contain only its maximum buffer size
5293 * \param pcm PCM handle
5294 * \param params Configuration space
5295 * \param val Returned maximum buffer size in frames
5296 * \return 0 otherwise a negative error code
5298 #ifndef DOXYGEN
5299 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)
5300 #else
5301 int snd_pcm_hw_params_set_buffer_size_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val)
5302 #endif
5304 unsigned int _val;
5305 int err = snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_BUFFER_SIZE, &_val, NULL);
5306 if (err >= 0)
5307 *val = _val;
5308 return err;
5313 * \brief (DEPRECATED) Extract tick time from a configuration space
5314 * \param params Configuration space
5315 * \param val Returned approximate tick duration in us
5316 * \param dir Sub unit direction
5317 * \return 0 otherwise a negative error code if the configuration space does not contain a single value
5319 * Actual exact value is <,=,> the approximate one following dir (-1, 0, 1)
5321 #ifndef DOXYGEN
5322 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)
5323 #else
5324 int snd_pcm_hw_params_get_tick_time(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
5325 #endif
5327 *val = 0;
5328 return 0;
5332 * \brief (DEPRECATED) Extract minimum tick time from a configuration space
5333 * \param params Configuration space
5334 * \param val Returned approximate minimum tick duration in us
5335 * \param dir Sub unit direction
5336 * \return 0 otherwise a negative error code
5338 * Exact value is <,=,> the returned one following dir (-1,0,1)
5340 #ifndef DOXYGEN
5341 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)
5342 #else
5343 int snd_pcm_hw_params_get_tick_time_min(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
5344 #endif
5346 *val = 0;
5347 return 0;
5351 * \brief (DEPRECATED) Extract maximum tick time from a configuration space
5352 * \param params Configuration space
5353 * \param val Returned approximate maximum tick duration in us
5354 * \param dir Sub unit direction
5355 * \return 0 otherwise a negative error code
5357 * Exact value is <,=,> the returned one following dir (-1,0,1)
5359 #ifndef DOXYGEN
5360 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)
5361 #else
5362 int snd_pcm_hw_params_get_tick_time_max(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
5363 #endif
5365 *val = 0;
5366 return 0;
5370 * \brief (DEPRECATED) Verify if a tick time is available inside a configuration space for a PCM
5371 * \param pcm PCM handle
5372 * \param params Configuration space
5373 * \param val approximate tick duration in us
5374 * \param dir Sub unit direction
5375 * \return 0 if available a negative error code otherwise
5377 * Wanted exact value is <,=,> val following dir (-1,0,1)
5379 int snd_pcm_hw_params_test_tick_time(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_hw_params_t *params ATTRIBUTE_UNUSED, unsigned int val, int dir ATTRIBUTE_UNUSED)
5381 return val ? -EINVAL : 0;
5385 * \brief (DEPRECATED) Restrict a configuration space to contain only one tick time
5386 * \param pcm PCM handle
5387 * \param params Configuration space
5388 * \param val approximate tick duration in us
5389 * \param dir Sub unit direction
5390 * \return 0 otherwise a negative error code if configuration space would become empty
5392 * Wanted exact value is <,=,> val following dir (-1,0,1)
5394 int snd_pcm_hw_params_set_tick_time(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_hw_params_t *params ATTRIBUTE_UNUSED, unsigned int val ATTRIBUTE_UNUSED, int dir ATTRIBUTE_UNUSED)
5396 return 0;
5400 * \brief (DEPRECATED) Restrict a configuration space with a minimum tick time
5401 * \param pcm PCM handle
5402 * \param params Configuration space
5403 * \param val approximate minimum tick duration in us (on return filled with actual minimum)
5404 * \param dir Sub unit direction (on return filled with actual direction)
5405 * \return 0 otherwise a negative error code if configuration space would become empty
5407 * Wanted/actual exact minimum is <,=,> val following dir (-1,0,1)
5409 int snd_pcm_hw_params_set_tick_time_min(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_hw_params_t *params ATTRIBUTE_UNUSED, unsigned int *val ATTRIBUTE_UNUSED, int *dir ATTRIBUTE_UNUSED)
5411 return 0;
5415 * \brief (DEPRECATED) Restrict a configuration space with a maximum tick time
5416 * \param pcm PCM handle
5417 * \param params Configuration space
5418 * \param val approximate maximum tick duration in us (on return filled with actual maximum)
5419 * \param dir Sub unit direction (on return filled with actual direction)
5420 * \return 0 otherwise a negative error code if configuration space would become empty
5422 * Wanted/actual exact maximum is <,=,> val following dir (-1,0,1)
5424 int snd_pcm_hw_params_set_tick_time_max(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_hw_params_t *params ATTRIBUTE_UNUSED, unsigned int *val ATTRIBUTE_UNUSED, int *dir ATTRIBUTE_UNUSED)
5426 return 0;
5430 * \brief (DEPRECATED) Restrict a configuration space to have tick times in a given range
5431 * \param pcm PCM handle
5432 * \param params Configuration space
5433 * \param min approximate minimum tick duration in us (on return filled with actual minimum)
5434 * \param mindir Sub unit direction for minimum (on return filled with actual direction)
5435 * \param max approximate maximum tick duration in us (on return filled with actual maximum)
5436 * \param maxdir Sub unit direction for maximum (on return filled with actual direction)
5437 * \return 0 otherwise a negative error code if configuration space would become empty
5439 * Wanted/actual exact min/max is <,=,> val following dir (-1,0,1)
5441 int snd_pcm_hw_params_set_tick_time_minmax(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_hw_params_t *params ATTRIBUTE_UNUSED, unsigned int *min ATTRIBUTE_UNUSED, int *mindir ATTRIBUTE_UNUSED, unsigned int *max ATTRIBUTE_UNUSED, int *maxdir ATTRIBUTE_UNUSED)
5443 return 0;
5447 * \brief (DEPRECATED) Restrict a configuration space to have tick time nearest to a target
5448 * \param pcm PCM handle
5449 * \param params Configuration space
5450 * \param val approximate target tick duration in us / returned chosen approximate target tick duration in us
5451 * \param dir Sub unit direction
5452 * \return 0 otherwise a negative error code if configuration space is empty
5454 * target/chosen exact value is <,=,> val following dir (-1,0,1)
5456 #ifndef DOXYGEN
5457 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)
5458 #else
5459 int snd_pcm_hw_params_set_tick_time_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
5460 #endif
5462 return 0;
5466 * \brief (DEPRECATED) Restrict a configuration space to contain only its minimum tick time
5467 * \param pcm PCM handle
5468 * \param params Configuration space
5469 * \param val Returned approximate minimum tick duration in us
5470 * \param dir Sub unit direction
5471 * \return 0 otherwise a negative error code
5473 * Actual exact value is <,=,> the approximate one following dir (-1, 0, 1)
5475 #ifndef DOXYGEN
5476 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)
5477 #else
5478 int snd_pcm_hw_params_set_tick_time_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
5479 #endif
5481 return 0;
5485 * \brief (DEPRECATED) Restrict a configuration space to contain only its maximum tick time
5486 * \param pcm PCM handle
5487 * \param params Configuration space
5488 * \param val Returned approximate maximum tick duration in us
5489 * \param dir Sub unit direction
5490 * \return 0 otherwise a negative error code
5492 * Actual exact value is <,=,> the approximate one following dir (-1, 0, 1)
5494 #ifndef DOXYGEN
5495 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)
5496 #else
5497 int snd_pcm_hw_params_set_tick_time_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
5498 #endif
5500 return 0;
5504 * \brief Get the minimum transfer align value in samples
5505 * \param params Configuration space
5506 * \param val Returned minimum align value
5507 * \return 0 otherwise a negative error code if the configuration space does not contain a single value
5509 int snd_pcm_hw_params_get_min_align(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val)
5511 unsigned int format, channels, fb, min_align;
5512 int err;
5514 err = snd_pcm_hw_param_get(params, SND_PCM_HW_PARAM_FORMAT, &format, NULL);
5515 if (err < 0)
5516 return err;
5517 err = snd_pcm_hw_param_get(params, SND_PCM_HW_PARAM_CHANNELS, &channels, NULL);
5518 if (err < 0)
5519 return err;
5520 // compute frame bits
5521 fb = snd_pcm_format_physical_width((snd_pcm_format_t)format) * channels;
5522 min_align = 1;
5523 while (fb % 8) {
5524 fb *= 2;
5525 min_align *= 2;
5527 if (val)
5528 *val = min_align;
5529 return 0;
5533 * \brief Return current software configuration for a PCM
5534 * \param pcm PCM handle
5535 * \param params Software configuration container
5536 * \return 0 on success otherwise a negative error code
5538 int snd_pcm_sw_params_current(snd_pcm_t *pcm, snd_pcm_sw_params_t *params)
5540 assert(pcm && params);
5541 if (CHECK_SANITY(! pcm->setup)) {
5542 SNDMSG("PCM not set up");
5543 return -EIO;
5545 params->tstamp_mode = pcm->tstamp_mode;
5546 params->period_step = pcm->period_step;
5547 params->sleep_min = 0;
5548 params->avail_min = pcm->avail_min;
5549 params->period_event = pcm->period_event;
5550 params->xfer_align = 1;
5551 params->start_threshold = pcm->start_threshold;
5552 params->stop_threshold = pcm->stop_threshold;
5553 params->silence_threshold = pcm->silence_threshold;
5554 params->silence_size = pcm->silence_size;
5555 params->boundary = pcm->boundary;
5556 return 0;
5560 * \brief Dump a software configuration
5561 * \param params Software configuration container
5562 * \param out Output handle
5563 * \return 0 on success otherwise a negative error code
5565 int snd_pcm_sw_params_dump(snd_pcm_sw_params_t *params, snd_output_t *out)
5567 snd_output_printf(out, "tstamp_mode: %s\n", snd_pcm_tstamp_mode_name(params->tstamp_mode));
5568 snd_output_printf(out, "period_step: %u\n", params->period_step);
5569 snd_output_printf(out, "avail_min: %lu\n", params->avail_min);
5570 snd_output_printf(out, "start_threshold: %ld\n", params->start_threshold);
5571 snd_output_printf(out, "stop_threshold: %ld\n", params->stop_threshold);
5572 snd_output_printf(out, "silence_threshold: %lu\n", params->silence_threshold);
5573 snd_output_printf(out, "silence_size: %lu\n", params->silence_size);
5574 snd_output_printf(out, "boundary: %lu\n", params->boundary);
5575 return 0;
5579 * \brief get size of #snd_pcm_sw_params_t
5580 * \return size in bytes
5582 size_t snd_pcm_sw_params_sizeof()
5584 return sizeof(snd_pcm_sw_params_t);
5588 * \brief allocate an invalid #snd_pcm_sw_params_t using standard malloc
5589 * \param ptr returned pointer
5590 * \return 0 on success otherwise negative error code
5592 int snd_pcm_sw_params_malloc(snd_pcm_sw_params_t **ptr)
5594 assert(ptr);
5595 *ptr = calloc(1, sizeof(snd_pcm_sw_params_t));
5596 if (!*ptr)
5597 return -ENOMEM;
5598 return 0;
5602 * \brief frees a previously allocated #snd_pcm_sw_params_t
5603 * \param obj pointer to object to free
5605 void snd_pcm_sw_params_free(snd_pcm_sw_params_t *obj)
5607 free(obj);
5611 * \brief copy one #snd_pcm_sw_params_t to another
5612 * \param dst pointer to destination
5613 * \param src pointer to source
5615 void snd_pcm_sw_params_copy(snd_pcm_sw_params_t *dst, const snd_pcm_sw_params_t *src)
5617 assert(dst && src);
5618 *dst = *src;
5622 * \brief Get boundary for ring pointers from a software configuration container
5623 * \param params Software configuration container
5624 * \param val Returned boundary in frames
5625 * \return 0 otherwise a negative error code
5627 int snd_pcm_sw_params_get_boundary(const snd_pcm_sw_params_t *params, snd_pcm_uframes_t *val)
5629 assert(params);
5630 *val = params->boundary;
5631 return 0;
5635 * \brief (DEPRECATED) Set start mode inside a software configuration container
5636 * \param pcm PCM handle
5637 * \param params Software configuration container
5638 * \param val Start mode
5639 * \return 0 otherwise a negative error code
5641 int snd_pcm_sw_params_set_start_mode(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_start_t val)
5643 assert(pcm && params);
5644 switch (val) {
5645 case SND_PCM_START_DATA:
5646 params->start_threshold = 1;
5647 break;
5648 case SND_PCM_START_EXPLICIT:
5649 params->start_threshold = pcm->boundary;
5650 break;
5651 default:
5652 SNDMSG("invalid start mode value %d\n", val);
5653 return -EINVAL;
5655 return 0;
5658 #ifndef DOC_HIDDEN
5659 link_warning(snd_pcm_sw_params_set_start_mode, "Warning: start_mode is deprecated, consider to use start_threshold");
5660 #endif
5663 * \brief (DEPRECATED) Get start mode from a software configuration container
5664 * \param params Software configuration container
5665 * \return start mode
5667 snd_pcm_start_t snd_pcm_sw_params_get_start_mode(const snd_pcm_sw_params_t *params)
5669 assert(params);
5670 /* FIXME: Ugly */
5671 return params->start_threshold > 1024 * 1024 ? SND_PCM_START_EXPLICIT : SND_PCM_START_DATA;
5674 #ifndef DOC_HIDDEN
5675 link_warning(snd_pcm_sw_params_get_start_mode, "Warning: start_mode is deprecated, consider to use start_threshold");
5676 #endif
5679 * \brief (DEPRECATED) Set xrun mode inside a software configuration container
5680 * \param pcm PCM handle
5681 * \param params Software configuration container
5682 * \param val Xrun mode
5683 * \return 0 otherwise a negative error code
5685 #ifndef DOXYGEN
5686 int snd_pcm_sw_params_set_xrun_mode(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_sw_params_t *params, snd_pcm_xrun_t val)
5687 #else
5688 int snd_pcm_sw_params_set_xrun_mode(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_xrun_t val)
5689 #endif
5691 assert(pcm && params);
5692 switch (val) {
5693 case SND_PCM_XRUN_STOP:
5694 params->stop_threshold = pcm->buffer_size;
5695 break;
5696 case SND_PCM_XRUN_NONE:
5697 params->stop_threshold = pcm->boundary;
5698 break;
5699 default:
5700 SNDMSG("invalid xrun mode value %d\n", val);
5701 return -EINVAL;
5703 return 0;
5706 #ifndef DOC_HIDDEN
5707 link_warning(snd_pcm_sw_params_set_xrun_mode, "Warning: xrun_mode is deprecated, consider to use stop_threshold");
5708 #endif
5711 * \brief (DEPRECATED) Get xrun mode from a software configuration container
5712 * \param params Software configuration container
5713 * \return xrun mode
5715 snd_pcm_xrun_t snd_pcm_sw_params_get_xrun_mode(const snd_pcm_sw_params_t *params)
5717 assert(params);
5718 /* FIXME: Ugly */
5719 return params->stop_threshold > 1024 * 1024 ? SND_PCM_XRUN_NONE : SND_PCM_XRUN_STOP;
5722 #ifndef DOC_HIDDEN
5723 link_warning(snd_pcm_sw_params_get_xrun_mode, "Warning: xrun_mode is deprecated, consider to use stop_threshold");
5724 #endif
5727 * \brief Set timestamp mode inside a software configuration container
5728 * \param pcm PCM handle
5729 * \param params Software configuration container
5730 * \param val Timestamp mode
5731 * \return 0 otherwise a negative error code
5733 #ifndef DOXYGEN
5734 int snd_pcm_sw_params_set_tstamp_mode(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_sw_params_t *params, snd_pcm_tstamp_t val)
5735 #else
5736 int snd_pcm_sw_params_set_tstamp_mode(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_tstamp_t val)
5737 #endif
5739 assert(pcm && params);
5740 if (CHECK_SANITY(val > SND_PCM_TSTAMP_LAST)) {
5741 SNDMSG("invalid tstamp_mode value %d", val);
5742 return -EINVAL;
5744 params->tstamp_mode = val;
5745 return 0;
5749 * \brief Get timestamp mode from a software configuration container
5750 * \param params Software configuration container
5751 * \param val Returned timestamp
5752 * \return 0 otherwise a negative error code
5754 #ifndef DOXYGEN
5755 int INTERNAL(snd_pcm_sw_params_get_tstamp_mode)(const snd_pcm_sw_params_t *params, snd_pcm_tstamp_t *val)
5756 #else
5757 int snd_pcm_sw_params_get_tstamp_mode(const snd_pcm_sw_params_t *params, snd_pcm_tstamp_t *val)
5758 #endif
5760 assert(params && val);
5761 *val = params->tstamp_mode;
5762 return 0;
5766 * \brief (DEPRECATED) Set minimum number of ticks to sleep inside a software configuration container
5767 * \param pcm PCM handle
5768 * \param params Software configuration container
5769 * \param val Minimum ticks to sleep or 0 to disable the use of tick timer
5770 * \return 0 otherwise a negative error code
5772 #ifndef DOXYGEN
5773 int snd_pcm_sw_params_set_sleep_min(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_sw_params_t *params ATTRIBUTE_UNUSED, unsigned int val ATTRIBUTE_UNUSED)
5774 #else
5775 int snd_pcm_sw_params_set_sleep_min(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, unsigned int val)
5776 #endif
5778 return 0;
5782 * \brief (DEPRECATED) Get minimum numbers of ticks to sleep from a software configuration container
5783 * \param params Software configuration container
5784 * \param val returned minimum number of ticks to sleep or 0 if tick timer is disabled
5785 * \return 0 otherwise a negative error code
5787 #ifndef DOXYGEN
5788 int INTERNAL(snd_pcm_sw_params_get_sleep_min)(const snd_pcm_sw_params_t *params ATTRIBUTE_UNUSED, unsigned int *val)
5789 #else
5790 int snd_pcm_sw_params_get_sleep_min(const snd_pcm_sw_params_t *params, unsigned int *val)
5791 #endif
5793 *val = 0;
5794 return 0;
5798 * \brief Set avail min inside a software configuration container
5799 * \param pcm PCM handle
5800 * \param params Software configuration container
5801 * \param val Minimum avail frames to consider PCM ready
5802 * \return 0 otherwise a negative error code
5804 * Note: This is similar to setting an OSS wakeup point. The valid
5805 * values for 'val' are determined by the specific hardware. Most PC
5806 * sound cards can only accept power of 2 frame counts (i.e. 512,
5807 * 1024, 2048). You cannot use this as a high resolution timer - it
5808 * is limited to how often the sound card hardware raises an
5809 * interrupt.
5811 #ifndef DOXYGEN
5812 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)
5813 #else
5814 int snd_pcm_sw_params_set_avail_min(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val)
5815 #endif
5817 assert(pcm && params);
5818 /* Fix avail_min if it's below period size. The period_size
5819 * defines the minimal wake-up timing accuracy, so it doesn't
5820 * make sense to set below that.
5822 if (val < pcm->period_size)
5823 val = pcm->period_size;
5824 params->avail_min = val;
5825 return 0;
5829 * \brief Get avail min from a software configuration container
5830 * \param params Software configuration container
5831 * \param val returned minimum available frames to consider PCM ready
5832 * \return 0 otherwise a negative error code
5834 #ifndef DOXYGEN
5835 int INTERNAL(snd_pcm_sw_params_get_avail_min)(const snd_pcm_sw_params_t *params, snd_pcm_uframes_t *val)
5836 #else
5837 int snd_pcm_sw_params_get_avail_min(const snd_pcm_sw_params_t *params, snd_pcm_uframes_t *val)
5838 #endif
5840 assert(params && val);
5841 *val = params->avail_min;
5842 return 0;
5846 * \brief Set period event inside a software configuration container
5847 * \param pcm PCM handle
5848 * \param params Software configuration container
5849 * \param val 0 = disable period event, 1 = enable period event
5850 * \return 0 otherwise a negative error code
5852 * An poll (select) wakeup event is raised if enabled.
5854 int snd_pcm_sw_params_set_period_event(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, int val)
5856 assert(pcm && params);
5857 params->period_event = val;
5858 return 0;
5862 * \brief Get period event from a software configuration container
5863 * \param params Software configuration container
5864 * \param val returned period event state
5865 * \return 0 otherwise a negative error code
5867 int snd_pcm_sw_params_get_period_event(const snd_pcm_sw_params_t *params, int *val)
5869 assert(params && val);
5870 *val = params->period_event;
5871 return 0;
5875 * \brief (DEPRECATED) Set xfer align inside a software configuration container
5876 * \param pcm PCM handle
5877 * \param params Software configuration container
5878 * \param val Chunk size (frames are attempted to be transferred in chunks)
5879 * \return 0 otherwise a negative error code
5881 #ifndef DOXYGEN
5882 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)
5883 #else
5884 int snd_pcm_sw_params_set_xfer_align(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val)
5885 #endif
5887 return 0;
5891 * \brief (DEPRECATED) Get xfer align from a software configuration container
5892 * \param params Software configuration container
5893 * \param val returned chunk size (frames are attempted to be transferred in chunks)
5894 * \return 0 otherwise a negative error code
5896 #ifndef DOXYGEN
5897 int INTERNAL(snd_pcm_sw_params_get_xfer_align)(const snd_pcm_sw_params_t *params ATTRIBUTE_UNUSED, snd_pcm_uframes_t *val)
5898 #else
5899 int snd_pcm_sw_params_get_xfer_align(const snd_pcm_sw_params_t *params, snd_pcm_uframes_t *val)
5900 #endif
5902 *val = 1;
5903 return 0;
5907 * \brief Set start threshold inside a software configuration container
5908 * \param pcm PCM handle
5909 * \param params Software configuration container
5910 * \param val Start threshold in frames
5911 * \return 0 otherwise a negative error code
5913 * PCM is automatically started when playback frames available to PCM
5914 * are >= threshold or when requested capture frames are >= threshold
5916 #ifndef DOXYGEN
5917 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)
5918 #else
5919 int snd_pcm_sw_params_set_start_threshold(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val)
5920 #endif
5922 assert(pcm && params);
5923 params->start_threshold = val;
5924 return 0;
5928 * \brief Get start threshold from a software configuration container
5929 * \param params Software configuration container
5930 * \param val Returned start threshold in frames
5931 * \return 0 otherwise a negative error code
5933 * PCM is automatically started when playback frames available to PCM
5934 * are >= threshold or when requested capture frames are >= threshold
5936 #ifndef DOXYGEN
5937 int INTERNAL(snd_pcm_sw_params_get_start_threshold)(const snd_pcm_sw_params_t *params, snd_pcm_uframes_t *val)
5938 #else
5939 int snd_pcm_sw_params_get_start_threshold(const snd_pcm_sw_params_t *params, snd_pcm_uframes_t *val)
5940 #endif
5942 assert(params);
5943 *val = params->start_threshold;
5944 return 0;
5949 * \brief Set stop threshold inside a software configuration container
5950 * \param pcm PCM handle
5951 * \param params Software configuration container
5952 * \param val Stop threshold in frames
5953 * \return 0 otherwise a negative error code
5955 * PCM is automatically stopped in #SND_PCM_STATE_XRUN state when available
5956 * frames is >= threshold. If the stop threshold is equal to boundary (also
5957 * software parameter - sw_param) then automatic stop will be disabled
5958 * (thus device will do the endless loop in the ring buffer).
5960 #ifndef DOXYGEN
5961 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)
5962 #else
5963 int snd_pcm_sw_params_set_stop_threshold(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val)
5964 #endif
5966 assert(pcm && params);
5967 params->stop_threshold = val;
5968 return 0;
5972 * \brief Get stop threshold from a software configuration container
5973 * \param params Software configuration container
5974 * \param val Returned stop threshold in frames
5975 * \return 0 otherwise a negative error code
5977 * PCM is automatically stopped in #SND_PCM_STATE_XRUN state when available
5978 * frames is >= threshold. If the stop threshold is equal to boundary (also
5979 * software parameter - sw_param) then automatic stop will be disabled
5980 * (thus device will do the endless loop in the ring buffer).
5982 #ifndef DOXYGEN
5983 int INTERNAL(snd_pcm_sw_params_get_stop_threshold)(const snd_pcm_sw_params_t *params, snd_pcm_uframes_t *val)
5984 #else
5985 int snd_pcm_sw_params_get_stop_threshold(const snd_pcm_sw_params_t *params, snd_pcm_uframes_t *val)
5986 #endif
5988 assert(params);
5989 *val = params->stop_threshold;
5990 return 0;
5995 * \brief Set silence threshold inside a software configuration container
5996 * \param pcm PCM handle
5997 * \param params Software configuration container
5998 * \param val Silence threshold in frames
5999 * \return 0 otherwise a negative error code
6001 * A portion of playback buffer is overwritten with silence (see
6002 * #snd_pcm_sw_params_set_silence_size) when playback underrun is nearer
6003 * than silence threshold.
6005 #ifndef DOXYGEN
6006 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)
6007 #else
6008 int snd_pcm_sw_params_set_silence_threshold(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val)
6009 #endif
6011 assert(pcm && params);
6012 if (CHECK_SANITY(val >= pcm->buffer_size)) {
6013 SNDMSG("invalid silent_threshold value %ld (buffer_size = %ld)",
6014 val, pcm->buffer_size);
6015 return -EINVAL;
6017 params->silence_threshold = val;
6018 return 0;
6022 * \brief Get silence threshold from a software configuration container
6023 * \param params Software configuration container
6024 * \param val Returned silence threshold in frames
6025 * \return 0 otherwise a negative error value
6027 * A portion of playback buffer is overwritten with silence (see
6028 * #snd_pcm_sw_params_set_silence_size) when playback underrun is nearer
6029 * than silence threshold.
6031 #ifndef DOXYGEN
6032 int INTERNAL(snd_pcm_sw_params_get_silence_threshold)(const snd_pcm_sw_params_t *params, snd_pcm_uframes_t *val)
6033 #else
6034 int snd_pcm_sw_params_get_silence_threshold(const snd_pcm_sw_params_t *params, snd_pcm_uframes_t *val)
6035 #endif
6037 assert(params && val);
6038 *val = params->silence_threshold;
6039 return 0;
6044 * \brief Set silence size inside a software configuration container
6045 * \param pcm PCM handle
6046 * \param params Software configuration container
6047 * \param val Silence size in frames (0 for disabled)
6048 * \return 0 otherwise a negative error code
6050 * A portion of playback buffer is overwritten with silence when playback
6051 * underrun is nearer than silence threshold (see
6052 * #snd_pcm_sw_params_set_silence_threshold)
6054 * The special case is when silence size value is equal or greater than
6055 * boundary. The unused portion of the ring buffer (initial written samples
6056 * are untouched) is filled with silence at start. Later, only just processed
6057 * sample area is filled with silence. Note: silence_threshold must be set to zero.
6059 #ifndef DOXYGEN
6060 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)
6061 #else
6062 int snd_pcm_sw_params_set_silence_size(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val)
6063 #endif
6065 assert(pcm && params);
6066 if (CHECK_SANITY(val < pcm->boundary && val > pcm->buffer_size)) {
6067 SNDMSG("invalid silence_size %ld (boundary %ld, buffer_size %ld)",
6068 val, pcm->boundary, pcm->buffer_size);
6069 return -EINVAL;
6071 params->silence_size = val;
6072 return 0;
6076 * \brief Get silence size from a software configuration container
6077 * \param params Software configuration container
6078 * \param val Returned silence size in frames (0 for disabled)
6079 * \return 0 otherwise a negative error code
6081 * A portion of playback buffer is overwritten with silence when playback
6082 * underrun is nearer than silence threshold (see
6083 * #snd_pcm_sw_params_set_silence_threshold)
6085 #ifndef DOXYGEN
6086 int INTERNAL(snd_pcm_sw_params_get_silence_size)(const snd_pcm_sw_params_t *params, snd_pcm_uframes_t *val)
6087 #else
6088 int snd_pcm_sw_params_get_silence_size(const snd_pcm_sw_params_t *params, snd_pcm_uframes_t *val)
6089 #endif
6091 assert(params);
6092 *val = params->silence_size;
6093 return 0;
6098 * \brief get size of #snd_pcm_status_t
6099 * \return size in bytes
6101 size_t snd_pcm_status_sizeof()
6103 return sizeof(snd_pcm_status_t);
6107 * \brief allocate an invalid #snd_pcm_status_t using standard malloc
6108 * \param ptr returned pointer
6109 * \return 0 on success otherwise negative error code
6111 int snd_pcm_status_malloc(snd_pcm_status_t **ptr)
6113 assert(ptr);
6114 *ptr = calloc(1, sizeof(snd_pcm_status_t));
6115 if (!*ptr)
6116 return -ENOMEM;
6117 return 0;
6121 * \brief frees a previously allocated #snd_pcm_status_t
6122 * \param obj pointer to object to free
6124 void snd_pcm_status_free(snd_pcm_status_t *obj)
6126 free(obj);
6130 * \brief copy one #snd_pcm_status_t to another
6131 * \param dst pointer to destination
6132 * \param src pointer to source
6134 void snd_pcm_status_copy(snd_pcm_status_t *dst, const snd_pcm_status_t *src)
6136 assert(dst && src);
6137 *dst = *src;
6141 * \brief Get state from a PCM status container (see #snd_pcm_state)
6142 * \param obj #snd_pcm_status_t pointer
6143 * \return PCM state
6145 snd_pcm_state_t snd_pcm_status_get_state(const snd_pcm_status_t *obj)
6147 assert(obj);
6148 return obj->state;
6152 * \brief Get trigger timestamp from a PCM status container
6153 * \param obj #snd_pcm_status_t pointer
6154 * \param ptr Pointer to returned timestamp
6156 * Trigger means a PCM state transition (from stopped to running or
6157 * versa vice). It applies also to pause and suspend. In other words,
6158 * timestamp contains time when stream started or when it was stopped.
6160 void snd_pcm_status_get_trigger_tstamp(const snd_pcm_status_t *obj, snd_timestamp_t *ptr)
6162 assert(obj && ptr);
6163 ptr->tv_sec = obj->trigger_tstamp.tv_sec;
6164 ptr->tv_usec = obj->trigger_tstamp.tv_nsec / 1000L;
6168 * \brief Get trigger hi-res timestamp from a PCM status container
6169 * \param obj #snd_pcm_status_t pointer
6170 * \param ptr Pointer to returned timestamp
6172 * Trigger means a PCM state transition (from stopped to running or
6173 * versa vice). It applies also to pause and suspend. In other words,
6174 * timestamp contains time when stream started or when it was stopped.
6176 #ifndef DOXYGEN
6177 void INTERNAL(snd_pcm_status_get_trigger_htstamp)(const snd_pcm_status_t *obj, snd_htimestamp_t *ptr)
6178 #else
6179 void snd_pcm_status_get_trigger_htstamp(const snd_pcm_status_t *obj, snd_htimestamp_t *ptr)
6180 #endif
6182 assert(obj && ptr);
6183 *ptr = obj->trigger_tstamp;
6185 use_default_symbol_version(__snd_pcm_status_get_trigger_htstamp, snd_pcm_status_get_trigger_htstamp, ALSA_0.9.0rc8);
6188 * \brief Get "now" timestamp from a PCM status container
6189 * \param obj #snd_pcm_status_t pointer
6190 * \param ptr Pointer to returned timestamp
6192 void snd_pcm_status_get_tstamp(const snd_pcm_status_t *obj, snd_timestamp_t *ptr)
6194 assert(obj && ptr);
6195 ptr->tv_sec = obj->tstamp.tv_sec;
6196 ptr->tv_usec = obj->tstamp.tv_nsec / 1000L;
6200 * \brief Get "now" hi-res timestamp from a PCM status container
6201 * \param obj pointer to #snd_pcm_status_t
6202 * \param ptr Pointer to returned timestamp
6204 #ifndef DOXYGEN
6205 void INTERNAL(snd_pcm_status_get_htstamp)(const snd_pcm_status_t *obj, snd_htimestamp_t *ptr)
6206 #else
6207 void snd_pcm_status_get_htstamp(const snd_pcm_status_t *obj, snd_htimestamp_t *ptr)
6208 #endif
6210 assert(obj && ptr);
6211 *ptr = obj->tstamp;
6213 use_default_symbol_version(__snd_pcm_status_get_htstamp, snd_pcm_status_get_htstamp, ALSA_0.9.0rc8);
6216 * \brief Get delay from a PCM status container (see #snd_pcm_delay)
6217 * \return Delay in frames
6219 * Delay is distance between current application frame position and
6220 * sound frame position.
6221 * It's positive and less than buffer size in normal situation,
6222 * negative on playback underrun and greater than buffer size on
6223 * capture overrun.
6225 snd_pcm_sframes_t snd_pcm_status_get_delay(const snd_pcm_status_t *obj)
6227 assert(obj);
6228 return obj->delay;
6232 * \brief Get number of frames available from a PCM status container (see #snd_pcm_avail_update)
6233 * \return Number of frames ready to be read/written
6235 snd_pcm_uframes_t snd_pcm_status_get_avail(const snd_pcm_status_t *obj)
6237 assert(obj);
6238 return obj->avail;
6242 * \brief Get maximum number of frames available from a PCM status container after last #snd_pcm_status call
6243 * \return Maximum number of frames ready to be read/written
6245 snd_pcm_uframes_t snd_pcm_status_get_avail_max(const snd_pcm_status_t *obj)
6247 assert(obj);
6248 return obj->avail_max;
6252 * \brief Get count of ADC overrange detections since last call
6253 * \return Count of ADC overrange detections
6255 snd_pcm_uframes_t snd_pcm_status_get_overrange(const snd_pcm_status_t *obj)
6257 assert(obj);
6258 return obj->overrange;
6262 * \brief get size of #snd_pcm_info_t
6263 * \return size in bytes
6265 size_t snd_pcm_info_sizeof()
6267 return sizeof(snd_pcm_info_t);
6271 * \brief allocate an invalid #snd_pcm_info_t using standard malloc
6272 * \param ptr returned pointer
6273 * \return 0 on success otherwise negative error code
6275 int snd_pcm_info_malloc(snd_pcm_info_t **ptr)
6277 assert(ptr);
6278 *ptr = calloc(1, sizeof(snd_pcm_info_t));
6279 if (!*ptr)
6280 return -ENOMEM;
6281 return 0;
6285 * \brief frees a previously allocated #snd_pcm_info_t
6286 * \param obj pointer to object to free
6288 void snd_pcm_info_free(snd_pcm_info_t *obj)
6290 free(obj);
6294 * \brief copy one #snd_pcm_info_t to another
6295 * \param dst pointer to destination
6296 * \param src pointer to source
6298 void snd_pcm_info_copy(snd_pcm_info_t *dst, const snd_pcm_info_t *src)
6300 assert(dst && src);
6301 *dst = *src;
6305 * \brief Get device from a PCM info container
6306 * \param obj PCM info container
6307 * \return device number
6309 unsigned int snd_pcm_info_get_device(const snd_pcm_info_t *obj)
6311 assert(obj);
6312 return obj->device;
6316 * \brief Get subdevice from a PCM info container
6317 * \param obj PCM info container
6318 * \return subdevice number
6320 unsigned int snd_pcm_info_get_subdevice(const snd_pcm_info_t *obj)
6322 assert(obj);
6323 return obj->subdevice;
6327 * \brief Get stream (direction) from a PCM info container
6328 * \param obj PCM info container
6329 * \return stream
6331 snd_pcm_stream_t snd_pcm_info_get_stream(const snd_pcm_info_t *obj)
6333 assert(obj);
6334 return obj->stream;
6338 * \brief Get card from a PCM info container
6339 * \param obj PCM info container
6340 * \return card number otherwise a negative error code if not associable to a card
6342 int snd_pcm_info_get_card(const snd_pcm_info_t *obj)
6344 assert(obj);
6345 return obj->card;
6349 * \brief Get id from a PCM info container
6350 * \param obj PCM info container
6351 * \return short id of PCM
6353 const char *snd_pcm_info_get_id(const snd_pcm_info_t *obj)
6355 assert(obj);
6356 return (const char *)obj->id;
6360 * \brief Get name from a PCM info container
6361 * \param obj PCM info container
6362 * \return name of PCM
6364 const char *snd_pcm_info_get_name(const snd_pcm_info_t *obj)
6366 assert(obj);
6367 return (const char *)obj->name;
6371 * \brief Get subdevice name from a PCM info container
6372 * \param obj PCM info container
6373 * \return name of used PCM subdevice
6375 const char *snd_pcm_info_get_subdevice_name(const snd_pcm_info_t *obj)
6377 assert(obj);
6378 return (const char *)obj->subname;
6382 * \brief Get class from a PCM info container
6383 * \param obj PCM info container
6384 * \return class of PCM
6386 snd_pcm_class_t snd_pcm_info_get_class(const snd_pcm_info_t *obj)
6388 assert(obj);
6389 return obj->dev_class;
6393 * \brief Get subclass from a PCM info container
6394 * \param obj PCM info container
6395 * \return subclass of PCM
6397 snd_pcm_subclass_t snd_pcm_info_get_subclass(const snd_pcm_info_t *obj)
6399 assert(obj);
6400 return obj->dev_subclass;
6404 * \brief Get subdevices count from a PCM info container
6405 * \param obj PCM info container
6406 * \return subdevices total count of PCM
6408 unsigned int snd_pcm_info_get_subdevices_count(const snd_pcm_info_t *obj)
6410 assert(obj);
6411 return obj->subdevices_count;
6415 * \brief Get available subdevices count from a PCM info container
6416 * \param obj PCM info container
6417 * \return available subdevices count of PCM
6419 unsigned int snd_pcm_info_get_subdevices_avail(const snd_pcm_info_t *obj)
6421 assert(obj);
6422 return obj->subdevices_avail;
6426 * \brief Get hardware synchronization ID from a PCM info container
6427 * \param obj PCM info container
6428 * \return hardware synchronization ID
6430 snd_pcm_sync_id_t snd_pcm_info_get_sync(const snd_pcm_info_t *obj)
6432 snd_pcm_sync_id_t res;
6433 assert(obj);
6434 memcpy(&res, &obj->sync, sizeof(res));
6435 return res;
6439 * \brief Set wanted device inside a PCM info container (see #snd_ctl_pcm_info)
6440 * \param obj PCM info container
6441 * \param val Device number
6443 void snd_pcm_info_set_device(snd_pcm_info_t *obj, unsigned int val)
6445 assert(obj);
6446 obj->device = val;
6450 * \brief Set wanted subdevice inside a PCM info container (see #snd_ctl_pcm_info)
6451 * \param obj PCM info container
6452 * \param val Subdevice number
6454 void snd_pcm_info_set_subdevice(snd_pcm_info_t *obj, unsigned int val)
6456 assert(obj);
6457 obj->subdevice = val;
6461 * \brief Set wanted stream inside a PCM info container (see #snd_ctl_pcm_info)
6462 * \param obj PCM info container
6463 * \param val Stream
6465 void snd_pcm_info_set_stream(snd_pcm_info_t *obj, snd_pcm_stream_t val)
6467 assert(obj);
6468 obj->stream = val;
6472 * \brief Application request to access a portion of direct (mmap) area
6473 * \param pcm PCM handle
6474 * \param areas Returned mmap channel areas
6475 * \param offset Returned mmap area offset in area steps (== frames)
6476 * \param frames mmap area portion size in frames (wanted on entry, contiguous available on exit)
6477 * \return 0 on success otherwise a negative error code
6479 * It is necessary to call the snd_pcm_avail_update() function directly before
6480 * this call. Otherwise, this function can return a wrong count of available frames.
6482 * The function should be called before a sample-direct area can be accessed.
6483 * The resulting size parameter is always less or equal to the input count of frames
6484 * and can be zero, if no frames can be processed (the ring buffer is full).
6486 * See the snd_pcm_mmap_commit() function to finish the frame processing in
6487 * the direct areas.
6489 int snd_pcm_mmap_begin(snd_pcm_t *pcm,
6490 const snd_pcm_channel_area_t **areas,
6491 snd_pcm_uframes_t *offset,
6492 snd_pcm_uframes_t *frames)
6494 snd_pcm_uframes_t cont;
6495 snd_pcm_uframes_t f;
6496 snd_pcm_uframes_t avail;
6497 const snd_pcm_channel_area_t *xareas;
6498 assert(pcm && areas && offset && frames);
6499 xareas = snd_pcm_mmap_areas(pcm);
6500 if (xareas == NULL)
6501 return -EBADFD;
6502 *areas = xareas;
6503 *offset = *pcm->appl.ptr % pcm->buffer_size;
6504 avail = snd_pcm_mmap_avail(pcm);
6505 if (avail > pcm->buffer_size)
6506 avail = pcm->buffer_size;
6507 cont = pcm->buffer_size - *offset;
6508 f = *frames;
6509 if (f > avail)
6510 f = avail;
6511 if (f > cont)
6512 f = cont;
6513 *frames = f;
6514 return 0;
6518 * \brief Application has completed the access to area requested with #snd_pcm_mmap_begin
6519 * \param pcm PCM handle
6520 * \param offset area offset in area steps (== frames)
6521 * \param frames area portion size in frames
6522 * \return count of transferred frames otherwise a negative error code
6524 * You should pass this function the offset value that
6525 * snd_pcm_mmap_begin() returned. The frames parameter should hold the
6526 * number of frames you have written or read to/from the audio
6527 * buffer. The frames parameter must never exceed the contiguous frames
6528 * count that snd_pcm_mmap_begin() returned. Each call to snd_pcm_mmap_begin()
6529 * must be followed by a call to snd_pcm_mmap_commit().
6531 * Example:
6532 \code
6533 double phase = 0;
6534 const snd_pcm_area_t *areas;
6535 snd_pcm_sframes_t avail, size, commitres;
6536 snd_pcm_uframes_t offset, frames;
6537 int err;
6539 avail = snd_pcm_avail_update(pcm);
6540 if (avail < 0)
6541 error(avail);
6542 // at this point, we can transfer at least 'avail' frames
6544 // we want to process frames in chunks (period_size)
6545 if (avail < period_size)
6546 goto _skip;
6547 size = period_size;
6548 // it is possible that contiguous areas are smaller, thus we use a loop
6549 while (size > 0) {
6550 frames = size;
6552 err = snd_pcm_mmap_begin(pcm_handle, &areas, &offset, &frames);
6553 if (err < 0)
6554 error(err);
6555 // this function fills the areas from offset with count of frames
6556 generate_sine(areas, offset, frames, &phase);
6557 commitres = snd_pcm_mmap_commit(pcm_handle, offset, frames);
6558 if (commitres < 0 || commitres != frames)
6559 error(commitres >= 0 ? -EPIPE : commitres);
6561 size -= frames;
6563 _skip:
6564 \endcode
6566 * Look to the \ref example_test_pcm "Sine-wave generator" example
6567 * for more details about the generate_sine function.
6569 snd_pcm_sframes_t snd_pcm_mmap_commit(snd_pcm_t *pcm,
6570 snd_pcm_uframes_t offset,
6571 snd_pcm_uframes_t frames)
6573 assert(pcm);
6574 if (CHECK_SANITY(offset != *pcm->appl.ptr % pcm->buffer_size)) {
6575 SNDMSG("commit offset (%ld) doesn't match with appl_ptr (%ld) %% buf_size (%ld)",
6576 offset, *pcm->appl.ptr, pcm->buffer_size);
6577 return -EPIPE;
6579 if (CHECK_SANITY(frames > snd_pcm_mmap_avail(pcm))) {
6580 SNDMSG("commit frames (%ld) overflow (avail = %ld)", frames,
6581 snd_pcm_mmap_avail(pcm));
6582 return -EPIPE;
6584 return pcm->fast_ops->mmap_commit(pcm->fast_op_arg, offset, frames);
6587 #ifndef DOC_HIDDEN
6589 int _snd_pcm_poll_descriptor(snd_pcm_t *pcm)
6591 assert(pcm);
6592 return pcm->poll_fd;
6595 void snd_pcm_areas_from_buf(snd_pcm_t *pcm, snd_pcm_channel_area_t *areas,
6596 void *buf)
6598 unsigned int channel;
6599 unsigned int channels = pcm->channels;
6600 for (channel = 0; channel < channels; ++channel, ++areas) {
6601 areas->addr = buf;
6602 areas->first = channel * pcm->sample_bits;
6603 areas->step = pcm->frame_bits;
6607 void snd_pcm_areas_from_bufs(snd_pcm_t *pcm, snd_pcm_channel_area_t *areas,
6608 void **bufs)
6610 unsigned int channel;
6611 unsigned int channels = pcm->channels;
6612 for (channel = 0; channel < channels; ++channel, ++areas, ++bufs) {
6613 areas->addr = *bufs;
6614 areas->first = 0;
6615 areas->step = pcm->sample_bits;
6619 snd_pcm_sframes_t snd_pcm_read_areas(snd_pcm_t *pcm, const snd_pcm_channel_area_t *areas,
6620 snd_pcm_uframes_t offset, snd_pcm_uframes_t size,
6621 snd_pcm_xfer_areas_func_t func)
6623 snd_pcm_uframes_t xfer = 0;
6624 snd_pcm_sframes_t err = 0;
6625 snd_pcm_state_t state;
6627 if (size == 0)
6628 return 0;
6630 while (size > 0) {
6631 snd_pcm_uframes_t frames;
6632 snd_pcm_sframes_t avail;
6633 _again:
6634 state = snd_pcm_state(pcm);
6635 switch (state) {
6636 case SND_PCM_STATE_PREPARED:
6637 err = snd_pcm_start(pcm);
6638 if (err < 0)
6639 goto _end;
6640 break;
6641 case SND_PCM_STATE_RUNNING:
6642 err = snd_pcm_hwsync(pcm);
6643 if (err < 0)
6644 goto _end;
6645 break;
6646 case SND_PCM_STATE_DRAINING:
6647 case SND_PCM_STATE_PAUSED:
6648 break;
6649 case SND_PCM_STATE_XRUN:
6650 err = -EPIPE;
6651 goto _end;
6652 case SND_PCM_STATE_SUSPENDED:
6653 err = -ESTRPIPE;
6654 goto _end;
6655 case SND_PCM_STATE_DISCONNECTED:
6656 err = -ENODEV;
6657 goto _end;
6658 default:
6659 err = -EBADFD;
6660 goto _end;
6662 avail = snd_pcm_avail_update(pcm);
6663 if (avail < 0) {
6664 err = avail;
6665 goto _end;
6667 if (avail == 0) {
6668 if (state == SND_PCM_STATE_DRAINING)
6669 goto _end;
6670 if (pcm->mode & SND_PCM_NONBLOCK) {
6671 err = -EAGAIN;
6672 goto _end;
6675 err = snd_pcm_wait(pcm, -1);
6676 if (err < 0)
6677 break;
6678 goto _again;
6681 frames = size;
6682 if (frames > (snd_pcm_uframes_t) avail)
6683 frames = avail;
6684 if (! frames)
6685 break;
6686 err = func(pcm, areas, offset, frames);
6687 if (err < 0)
6688 break;
6689 frames = err;
6690 offset += frames;
6691 size -= frames;
6692 xfer += frames;
6694 _end:
6695 return xfer > 0 ? (snd_pcm_sframes_t) xfer : snd_pcm_check_error(pcm, err);
6698 snd_pcm_sframes_t snd_pcm_write_areas(snd_pcm_t *pcm, const snd_pcm_channel_area_t *areas,
6699 snd_pcm_uframes_t offset, snd_pcm_uframes_t size,
6700 snd_pcm_xfer_areas_func_t func)
6702 snd_pcm_uframes_t xfer = 0;
6703 snd_pcm_sframes_t err = 0;
6704 snd_pcm_state_t state;
6706 if (size == 0)
6707 return 0;
6709 while (size > 0) {
6710 snd_pcm_uframes_t frames;
6711 snd_pcm_sframes_t avail;
6712 _again:
6713 state = snd_pcm_state(pcm);
6714 switch (state) {
6715 case SND_PCM_STATE_PREPARED:
6716 case SND_PCM_STATE_PAUSED:
6717 break;
6718 case SND_PCM_STATE_RUNNING:
6719 err = snd_pcm_hwsync(pcm);
6720 if (err < 0)
6721 goto _end;
6722 break;
6723 case SND_PCM_STATE_XRUN:
6724 err = -EPIPE;
6725 goto _end;
6726 case SND_PCM_STATE_SUSPENDED:
6727 err = -ESTRPIPE;
6728 goto _end;
6729 case SND_PCM_STATE_DISCONNECTED:
6730 err = -ENODEV;
6731 goto _end;
6732 default:
6733 err = -EBADFD;
6734 goto _end;
6736 avail = snd_pcm_avail_update(pcm);
6737 if (avail < 0) {
6738 err = avail;
6739 goto _end;
6741 if ((state == SND_PCM_STATE_RUNNING &&
6742 (snd_pcm_uframes_t)avail < pcm->avail_min &&
6743 size > (snd_pcm_uframes_t)avail)) {
6744 if (pcm->mode & SND_PCM_NONBLOCK) {
6745 err = -EAGAIN;
6746 goto _end;
6749 err = snd_pcm_wait(pcm, -1);
6750 if (err < 0)
6751 break;
6752 goto _again;
6754 frames = size;
6755 if (frames > (snd_pcm_uframes_t) avail)
6756 frames = avail;
6757 if (! frames)
6758 break;
6759 err = func(pcm, areas, offset, frames);
6760 if (err < 0)
6761 break;
6762 frames = err;
6763 if (state == SND_PCM_STATE_PREPARED) {
6764 snd_pcm_sframes_t hw_avail = pcm->buffer_size - avail;
6765 hw_avail += frames;
6766 /* some plugins might automatically start the stream */
6767 state = snd_pcm_state(pcm);
6768 if (state == SND_PCM_STATE_PREPARED &&
6769 hw_avail >= (snd_pcm_sframes_t) pcm->start_threshold) {
6770 err = snd_pcm_start(pcm);
6771 if (err < 0)
6772 goto _end;
6775 offset += frames;
6776 size -= frames;
6777 xfer += frames;
6779 _end:
6780 return xfer > 0 ? (snd_pcm_sframes_t) xfer : snd_pcm_check_error(pcm, err);
6783 snd_pcm_uframes_t _snd_pcm_mmap_hw_ptr(snd_pcm_t *pcm)
6785 return *pcm->hw.ptr;
6788 snd_pcm_uframes_t _snd_pcm_boundary(snd_pcm_t *pcm)
6790 return pcm->boundary;
6793 #ifndef DOC_HIDDEN
6794 link_warning(_snd_pcm_mmap_hw_ptr, "Warning: _snd_pcm_mmap_hw_ptr() is deprecated, consider to not use this function");
6795 link_warning(_snd_pcm_boundary, "Warning: _snd_pcm_boundary() is deprecated, consider to use snd_pcm_sw_params_current()");
6796 #endif
6798 static const char *const names[SND_PCM_HW_PARAM_LAST_INTERVAL + 1] = {
6799 [SND_PCM_HW_PARAM_FORMAT] = "format",
6800 [SND_PCM_HW_PARAM_CHANNELS] = "channels",
6801 [SND_PCM_HW_PARAM_RATE] = "rate",
6802 [SND_PCM_HW_PARAM_PERIOD_TIME] = "period_time",
6803 [SND_PCM_HW_PARAM_PERIOD_SIZE] = "period_size",
6804 [SND_PCM_HW_PARAM_BUFFER_TIME] = "buffer_time",
6805 [SND_PCM_HW_PARAM_BUFFER_SIZE] = "buffer_size",
6806 [SND_PCM_HW_PARAM_PERIODS] = "periods"
6809 int snd_pcm_slave_conf(snd_config_t *root, snd_config_t *conf,
6810 snd_config_t **_pcm_conf, unsigned int count, ...)
6812 snd_config_iterator_t i, next;
6813 const char *str;
6814 struct {
6815 unsigned int index;
6816 int flags;
6817 void *ptr;
6818 int present;
6819 } fields[count];
6820 unsigned int k;
6821 snd_config_t *pcm_conf = NULL;
6822 int err;
6823 int to_free = 0;
6824 va_list args;
6825 assert(root);
6826 assert(conf);
6827 assert(_pcm_conf);
6828 if (snd_config_get_string(conf, &str) >= 0) {
6829 err = snd_config_search_definition(root, "pcm_slave", str, &conf);
6830 if (err < 0) {
6831 SNDERR("Invalid slave definition");
6832 return -EINVAL;
6834 to_free = 1;
6836 if (snd_config_get_type(conf) != SND_CONFIG_TYPE_COMPOUND) {
6837 SNDERR("Invalid slave definition");
6838 err = -EINVAL;
6839 goto _err;
6841 va_start(args, count);
6842 for (k = 0; k < count; ++k) {
6843 fields[k].index = va_arg(args, int);
6844 fields[k].flags = va_arg(args, int);
6845 fields[k].ptr = va_arg(args, void *);
6846 fields[k].present = 0;
6848 va_end(args);
6849 snd_config_for_each(i, next, conf) {
6850 snd_config_t *n = snd_config_iterator_entry(i);
6851 const char *id;
6852 if (snd_config_get_id(n, &id) < 0)
6853 continue;
6854 if (strcmp(id, "comment") == 0)
6855 continue;
6856 if (strcmp(id, "pcm") == 0) {
6857 if (pcm_conf != NULL)
6858 snd_config_delete(pcm_conf);
6859 if ((err = snd_config_copy(&pcm_conf, n)) < 0)
6860 goto _err;
6861 continue;
6863 for (k = 0; k < count; ++k) {
6864 unsigned int idx = fields[k].index;
6865 long v;
6866 assert(idx < SND_PCM_HW_PARAM_LAST_INTERVAL);
6867 assert(names[idx]);
6868 if (strcmp(id, names[idx]) != 0)
6869 continue;
6870 switch (idx) {
6871 case SND_PCM_HW_PARAM_FORMAT:
6873 snd_pcm_format_t f;
6874 err = snd_config_get_string(n, &str);
6875 if (err < 0) {
6876 _invalid:
6877 SNDERR("invalid type for %s", id);
6878 goto _err;
6880 if ((fields[k].flags & SCONF_UNCHANGED) &&
6881 strcasecmp(str, "unchanged") == 0) {
6882 *(snd_pcm_format_t*)fields[k].ptr = (snd_pcm_format_t) -2;
6883 break;
6885 f = snd_pcm_format_value(str);
6886 if (f == SND_PCM_FORMAT_UNKNOWN) {
6887 SNDERR("unknown format %s", str);
6888 err = -EINVAL;
6889 goto _err;
6891 *(snd_pcm_format_t*)fields[k].ptr = f;
6892 break;
6894 default:
6895 if ((fields[k].flags & SCONF_UNCHANGED)) {
6896 err = snd_config_get_string(n, &str);
6897 if (err >= 0 &&
6898 strcasecmp(str, "unchanged") == 0) {
6899 *(int*)fields[k].ptr = -2;
6900 break;
6903 err = snd_config_get_integer(n, &v);
6904 if (err < 0)
6905 goto _invalid;
6906 *(int*)fields[k].ptr = v;
6907 break;
6909 fields[k].present = 1;
6910 break;
6912 if (k < count)
6913 continue;
6914 SNDERR("Unknown field %s", id);
6915 err = -EINVAL;
6916 goto _err;
6918 if (!pcm_conf) {
6919 SNDERR("missing field pcm");
6920 err = -EINVAL;
6921 goto _err;
6923 for (k = 0; k < count; ++k) {
6924 if ((fields[k].flags & SCONF_MANDATORY) && !fields[k].present) {
6925 SNDERR("missing field %s", names[fields[k].index]);
6926 err = -EINVAL;
6927 goto _err;
6930 *_pcm_conf = pcm_conf;
6931 pcm_conf = NULL;
6932 err = 0;
6933 _err:
6934 if (pcm_conf)
6935 snd_config_delete(pcm_conf);
6936 if (to_free)
6937 snd_config_delete(conf);
6938 return err;
6942 int snd_pcm_conf_generic_id(const char *id)
6944 static const char ids[3][8] = { "comment", "type", "hint" };
6945 unsigned int k;
6946 for (k = 0; k < sizeof(ids) / sizeof(ids[0]); ++k) {
6947 if (strcmp(id, ids[k]) == 0)
6948 return 1;
6950 return 0;
6953 static void snd_pcm_set_ptr(snd_pcm_t *pcm, snd_pcm_rbptr_t *rbptr,
6954 volatile snd_pcm_uframes_t *hw_ptr, int fd, off_t offset)
6956 rbptr->master = NULL; /* I'm master */
6957 rbptr->ptr = hw_ptr;
6958 rbptr->fd = fd;
6959 rbptr->offset = offset;
6960 if (rbptr->changed)
6961 rbptr->changed(pcm, NULL);
6964 void snd_pcm_set_hw_ptr(snd_pcm_t *pcm, volatile snd_pcm_uframes_t *hw_ptr, int fd, off_t offset)
6966 assert(pcm);
6967 assert(hw_ptr);
6968 snd_pcm_set_ptr(pcm, &pcm->hw, hw_ptr, fd, offset);
6971 void snd_pcm_set_appl_ptr(snd_pcm_t *pcm, volatile snd_pcm_uframes_t *appl_ptr, int fd, off_t offset)
6973 assert(pcm);
6974 assert(appl_ptr);
6975 snd_pcm_set_ptr(pcm, &pcm->appl, appl_ptr, fd, offset);
6978 static void snd_pcm_link_ptr(snd_pcm_t *pcm, snd_pcm_rbptr_t *pcm_rbptr,
6979 snd_pcm_t *slave, snd_pcm_rbptr_t *slave_rbptr)
6981 snd_pcm_t **a;
6982 int idx;
6984 a = slave_rbptr->link_dst;
6985 for (idx = 0; idx < slave_rbptr->link_dst_count; idx++)
6986 if (a[idx] == NULL) {
6987 a[idx] = pcm;
6988 goto __found_free_place;
6990 a = realloc(a, sizeof(snd_pcm_t *) * (slave_rbptr->link_dst_count + 1));
6991 if (a == NULL) {
6992 pcm_rbptr->ptr = NULL;
6993 pcm_rbptr->fd = -1;
6994 pcm_rbptr->offset = 0UL;
6995 return;
6997 a[slave_rbptr->link_dst_count++] = pcm;
6998 __found_free_place:
6999 pcm_rbptr->master = slave_rbptr->master ? slave_rbptr->master : slave;
7000 pcm_rbptr->ptr = slave_rbptr->ptr;
7001 pcm_rbptr->fd = slave_rbptr->fd;
7002 pcm_rbptr->offset = slave_rbptr->offset;
7003 slave_rbptr->link_dst = a;
7004 if (pcm_rbptr->changed)
7005 pcm_rbptr->changed(pcm, slave);
7008 static void snd_pcm_unlink_ptr(snd_pcm_t *pcm, snd_pcm_rbptr_t *pcm_rbptr,
7009 snd_pcm_t *slave, snd_pcm_rbptr_t *slave_rbptr)
7011 snd_pcm_t **a;
7012 int idx;
7014 a = slave_rbptr->link_dst;
7015 for (idx = 0; idx < slave_rbptr->link_dst_count; idx++) {
7016 if (a[idx] == pcm) {
7017 a[idx] = NULL;
7018 goto __found;
7021 /* assert(0); */
7022 return;
7024 __found:
7025 pcm_rbptr->master = NULL;
7026 pcm_rbptr->ptr = NULL;
7027 pcm_rbptr->fd = -1;
7028 pcm_rbptr->offset = 0UL;
7029 if (pcm_rbptr->changed)
7030 pcm_rbptr->changed(pcm, slave);
7033 void snd_pcm_link_hw_ptr(snd_pcm_t *pcm, snd_pcm_t *slave)
7035 assert(pcm);
7036 assert(slave);
7037 snd_pcm_link_ptr(pcm, &pcm->hw, slave, &slave->hw);
7040 void snd_pcm_link_appl_ptr(snd_pcm_t *pcm, snd_pcm_t *slave)
7042 assert(pcm);
7043 assert(slave);
7044 snd_pcm_link_ptr(pcm, &pcm->appl, slave, &slave->appl);
7047 void snd_pcm_unlink_hw_ptr(snd_pcm_t *pcm, snd_pcm_t *slave)
7049 assert(pcm);
7050 assert(slave);
7051 snd_pcm_unlink_ptr(pcm, &pcm->hw, slave, &slave->hw);
7054 void snd_pcm_unlink_appl_ptr(snd_pcm_t *pcm, snd_pcm_t *slave)
7056 assert(pcm);
7057 assert(slave);
7058 snd_pcm_unlink_ptr(pcm, &pcm->appl, slave, &slave->appl);
7061 #endif /* DOC_HIDDEN */
7067 #ifndef DOC_HIDDEN
7069 #ifdef USE_VERSIONED_SYMBOLS
7071 #define OBSOLETE1(name, what, new) \
7072 default_symbol_version(__##name, name, new); \
7073 symbol_version(__old_##name, name, what);
7075 #else
7077 #define OBSOLETE1(name, what, new) \
7078 use_default_symbol_version(__##name, name, new);
7080 #endif /* USE_VERSIONED_SYMBOLS */
7082 #define __P_OLD_GET(pfx, name, val_type, ret_type) \
7083 ret_type pfx##name(const snd_pcm_hw_params_t *params) \
7085 val_type val; \
7086 if (INTERNAL(name)(params, &val) < 0) \
7087 return 0; \
7088 return (ret_type)val; \
7091 #define __P_OLD_GET1(pfx, name, val_type, ret_type) \
7092 ret_type pfx##name(const snd_pcm_hw_params_t *params, int *dir) \
7094 val_type val; \
7095 if (INTERNAL(name)(params, &val, dir) < 0) \
7096 return 0; \
7097 return (ret_type)val; \
7100 #define __OLD_GET(name, val_type, ret_type) __P_OLD_GET(__old_, name, val_type, ret_type)
7101 #define __OLD_GET1(name, val_type, ret_type) __P_OLD_GET1(__old_, name, val_type, ret_type)
7103 __OLD_GET(snd_pcm_hw_params_get_access, snd_pcm_access_t, int);
7104 __OLD_GET(snd_pcm_hw_params_get_format, snd_pcm_format_t, int);
7105 __OLD_GET(snd_pcm_hw_params_get_subformat, snd_pcm_subformat_t, int);
7106 __OLD_GET(snd_pcm_hw_params_get_channels, unsigned int, int);
7107 __OLD_GET1(snd_pcm_hw_params_get_rate, unsigned int, int);
7108 __OLD_GET1(snd_pcm_hw_params_get_period_time, unsigned int, int);
7109 __OLD_GET1(snd_pcm_hw_params_get_period_size, snd_pcm_uframes_t, snd_pcm_sframes_t);
7110 __OLD_GET1(snd_pcm_hw_params_get_periods, unsigned int, int);
7111 __OLD_GET1(snd_pcm_hw_params_get_buffer_time, unsigned int, int);
7112 __OLD_GET(snd_pcm_hw_params_get_buffer_size, snd_pcm_uframes_t, snd_pcm_sframes_t);
7113 __OLD_GET1(snd_pcm_hw_params_get_tick_time, unsigned int, int);
7115 __OLD_GET(snd_pcm_hw_params_get_channels_min, unsigned int, unsigned int);
7116 __OLD_GET1(snd_pcm_hw_params_get_rate_min, unsigned int, unsigned int);
7117 __OLD_GET1(snd_pcm_hw_params_get_period_time_min, unsigned int, unsigned int);
7118 __OLD_GET1(snd_pcm_hw_params_get_period_size_min, snd_pcm_uframes_t, snd_pcm_uframes_t);
7119 __OLD_GET1(snd_pcm_hw_params_get_periods_min, unsigned int, unsigned int);
7120 __OLD_GET1(snd_pcm_hw_params_get_buffer_time_min, unsigned int, unsigned int);
7121 __OLD_GET(snd_pcm_hw_params_get_buffer_size_min, snd_pcm_uframes_t, snd_pcm_uframes_t);
7122 __OLD_GET1(snd_pcm_hw_params_get_tick_time_min, unsigned int, unsigned int);
7124 __OLD_GET(snd_pcm_hw_params_get_channels_max, unsigned int, unsigned int);
7125 __OLD_GET1(snd_pcm_hw_params_get_rate_max, unsigned int, unsigned int);
7126 __OLD_GET1(snd_pcm_hw_params_get_period_time_max, unsigned int, unsigned int);
7127 __OLD_GET1(snd_pcm_hw_params_get_period_size_max, snd_pcm_uframes_t, snd_pcm_uframes_t);
7128 __OLD_GET1(snd_pcm_hw_params_get_periods_max, unsigned int, unsigned int);
7129 __OLD_GET1(snd_pcm_hw_params_get_buffer_time_max, unsigned int, unsigned int);
7130 __OLD_GET(snd_pcm_hw_params_get_buffer_size_max, snd_pcm_uframes_t, snd_pcm_uframes_t);
7131 __OLD_GET1(snd_pcm_hw_params_get_tick_time_max, unsigned int, unsigned int);
7133 #define __P_OLD_NEAR(pfx, name, ret_type) \
7134 ret_type pfx##name(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, ret_type val) \
7136 if (INTERNAL(name)(pcm, params, &val) < 0) \
7137 return 0; \
7138 return (ret_type)val; \
7141 #define __P_OLD_NEAR1(pfx, name, ret_type) \
7142 ret_type pfx##name(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, ret_type val, int *dir) \
7144 if (INTERNAL(name)(pcm, params, &val, dir) < 0) \
7145 return 0; \
7146 return (ret_type)val; \
7149 #define __OLD_NEAR(name, ret_type) __P_OLD_NEAR(__old_, name, ret_type)
7150 #define __OLD_NEAR1(name, ret_type) __P_OLD_NEAR1(__old_, name, ret_type)
7152 __OLD_NEAR(snd_pcm_hw_params_set_channels_near, unsigned int);
7153 __OLD_NEAR1(snd_pcm_hw_params_set_rate_near, unsigned int);
7154 __OLD_NEAR1(snd_pcm_hw_params_set_period_time_near, unsigned int);
7155 __OLD_NEAR1(snd_pcm_hw_params_set_period_size_near, snd_pcm_uframes_t);
7156 __OLD_NEAR1(snd_pcm_hw_params_set_periods_near, unsigned int);
7157 __OLD_NEAR1(snd_pcm_hw_params_set_buffer_time_near, unsigned int);
7158 __OLD_NEAR(snd_pcm_hw_params_set_buffer_size_near, snd_pcm_uframes_t);
7159 __OLD_NEAR1(snd_pcm_hw_params_set_tick_time_near, unsigned int);
7161 #define __P_OLD_SET_FL(pfx, name, ret_type) \
7162 ret_type pfx##name(snd_pcm_t *pcm, snd_pcm_hw_params_t *params) \
7164 ret_type val; \
7165 if (INTERNAL(name)(pcm, params, &val) < 0) \
7166 return 0; \
7167 return (ret_type)val; \
7170 #define __P_OLD_SET_FL1(pfx, name, ret_type) \
7171 ret_type pfx##name(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir) \
7173 ret_type val; \
7174 if (INTERNAL(name)(pcm, params, &val, dir) < 0) \
7175 return 0; \
7176 return (ret_type)val; \
7179 #define __OLD_SET_FL(name, ret_type) __P_OLD_SET_FL(__old_, name, ret_type)
7180 #define __OLD_SET_FL1(name, ret_type) __P_OLD_SET_FL1(__old_, name, ret_type)
7182 __OLD_SET_FL(snd_pcm_hw_params_set_access_first, snd_pcm_access_t);
7183 __OLD_SET_FL(snd_pcm_hw_params_set_format_first, snd_pcm_format_t);
7184 __OLD_SET_FL(snd_pcm_hw_params_set_subformat_first, snd_pcm_subformat_t);
7185 __OLD_SET_FL(snd_pcm_hw_params_set_channels_first, unsigned int);
7186 __OLD_SET_FL1(snd_pcm_hw_params_set_rate_first, unsigned int);
7187 __OLD_SET_FL1(snd_pcm_hw_params_set_period_time_first, unsigned int);
7188 __OLD_SET_FL1(snd_pcm_hw_params_set_period_size_first, snd_pcm_uframes_t);
7189 __OLD_SET_FL1(snd_pcm_hw_params_set_periods_first, unsigned int);
7190 __OLD_SET_FL1(snd_pcm_hw_params_set_buffer_time_first, unsigned int);
7191 __OLD_SET_FL(snd_pcm_hw_params_set_buffer_size_first, snd_pcm_uframes_t);
7192 __OLD_SET_FL1(snd_pcm_hw_params_set_tick_time_first, unsigned int);
7194 __OLD_SET_FL(snd_pcm_hw_params_set_access_last, snd_pcm_access_t);
7195 __OLD_SET_FL(snd_pcm_hw_params_set_format_last, snd_pcm_format_t);
7196 __OLD_SET_FL(snd_pcm_hw_params_set_subformat_last, snd_pcm_subformat_t);
7197 __OLD_SET_FL(snd_pcm_hw_params_set_channels_last, unsigned int);
7198 __OLD_SET_FL1(snd_pcm_hw_params_set_rate_last, unsigned int);
7199 __OLD_SET_FL1(snd_pcm_hw_params_set_period_time_last, unsigned int);
7200 __OLD_SET_FL1(snd_pcm_hw_params_set_period_size_last, snd_pcm_uframes_t);
7201 __OLD_SET_FL1(snd_pcm_hw_params_set_periods_last, unsigned int);
7202 __OLD_SET_FL1(snd_pcm_hw_params_set_buffer_time_last, unsigned int);
7203 __OLD_SET_FL(snd_pcm_hw_params_set_buffer_size_last, snd_pcm_uframes_t);
7204 __OLD_SET_FL1(snd_pcm_hw_params_set_tick_time_last, unsigned int);
7206 #define __P_OLD_GET_SW(pfx, name, ret_type) \
7207 ret_type pfx##name(snd_pcm_sw_params_t *params) \
7209 ret_type val; \
7210 if (INTERNAL(name)(params, &val) < 0) \
7211 return 0; \
7212 return (ret_type)val; \
7215 #define __OLD_GET_SW(name, ret_type) __P_OLD_GET_SW(__old_, name, ret_type)
7217 __OLD_GET_SW(snd_pcm_sw_params_get_tstamp_mode, snd_pcm_tstamp_t);
7218 __OLD_GET_SW(snd_pcm_sw_params_get_sleep_min, unsigned int);
7219 __OLD_GET_SW(snd_pcm_sw_params_get_avail_min, snd_pcm_uframes_t);
7220 __OLD_GET_SW(snd_pcm_sw_params_get_xfer_align, snd_pcm_uframes_t);
7221 __OLD_GET_SW(snd_pcm_sw_params_get_start_threshold, snd_pcm_uframes_t);
7222 __OLD_GET_SW(snd_pcm_sw_params_get_stop_threshold, snd_pcm_uframes_t);
7223 __OLD_GET_SW(snd_pcm_sw_params_get_silence_threshold, snd_pcm_uframes_t);
7224 __OLD_GET_SW(snd_pcm_sw_params_get_silence_size, snd_pcm_uframes_t);
7226 OBSOLETE1(snd_pcm_hw_params_get_access, ALSA_0.9, ALSA_0.9.0rc4);
7227 OBSOLETE1(snd_pcm_hw_params_set_access_first, ALSA_0.9, ALSA_0.9.0rc4);
7228 OBSOLETE1(snd_pcm_hw_params_set_access_last, ALSA_0.9, ALSA_0.9.0rc4);
7230 OBSOLETE1(snd_pcm_hw_params_get_format, ALSA_0.9, ALSA_0.9.0rc4);
7231 OBSOLETE1(snd_pcm_hw_params_set_format_first, ALSA_0.9, ALSA_0.9.0rc4);
7232 OBSOLETE1(snd_pcm_hw_params_set_format_last, ALSA_0.9, ALSA_0.9.0rc4);
7234 OBSOLETE1(snd_pcm_hw_params_get_subformat, ALSA_0.9, ALSA_0.9.0rc4);
7235 OBSOLETE1(snd_pcm_hw_params_set_subformat_first, ALSA_0.9, ALSA_0.9.0rc4);
7236 OBSOLETE1(snd_pcm_hw_params_set_subformat_last, ALSA_0.9, ALSA_0.9.0rc4);
7238 OBSOLETE1(snd_pcm_hw_params_get_channels, ALSA_0.9, ALSA_0.9.0rc4);
7239 OBSOLETE1(snd_pcm_hw_params_get_channels_min, ALSA_0.9, ALSA_0.9.0rc4);
7240 OBSOLETE1(snd_pcm_hw_params_get_channels_max, ALSA_0.9, ALSA_0.9.0rc4);
7241 OBSOLETE1(snd_pcm_hw_params_set_channels_near, ALSA_0.9, ALSA_0.9.0rc4);
7242 OBSOLETE1(snd_pcm_hw_params_set_channels_first, ALSA_0.9, ALSA_0.9.0rc4);
7243 OBSOLETE1(snd_pcm_hw_params_set_channels_last, ALSA_0.9, ALSA_0.9.0rc4);
7245 OBSOLETE1(snd_pcm_hw_params_get_rate, ALSA_0.9, ALSA_0.9.0rc4);
7246 OBSOLETE1(snd_pcm_hw_params_get_rate_min, ALSA_0.9, ALSA_0.9.0rc4);
7247 OBSOLETE1(snd_pcm_hw_params_get_rate_max, ALSA_0.9, ALSA_0.9.0rc4);
7248 OBSOLETE1(snd_pcm_hw_params_set_rate_near, ALSA_0.9, ALSA_0.9.0rc4);
7249 OBSOLETE1(snd_pcm_hw_params_set_rate_first, ALSA_0.9, ALSA_0.9.0rc4);
7250 OBSOLETE1(snd_pcm_hw_params_set_rate_last, ALSA_0.9, ALSA_0.9.0rc4);
7252 OBSOLETE1(snd_pcm_hw_params_get_period_time, ALSA_0.9, ALSA_0.9.0rc4);
7253 OBSOLETE1(snd_pcm_hw_params_get_period_time_min, ALSA_0.9, ALSA_0.9.0rc4);
7254 OBSOLETE1(snd_pcm_hw_params_get_period_time_max, ALSA_0.9, ALSA_0.9.0rc4);
7255 OBSOLETE1(snd_pcm_hw_params_set_period_time_near, ALSA_0.9, ALSA_0.9.0rc4);
7256 OBSOLETE1(snd_pcm_hw_params_set_period_time_first, ALSA_0.9, ALSA_0.9.0rc4);
7257 OBSOLETE1(snd_pcm_hw_params_set_period_time_last, ALSA_0.9, ALSA_0.9.0rc4);
7259 OBSOLETE1(snd_pcm_hw_params_get_period_size, ALSA_0.9, ALSA_0.9.0rc4);
7260 OBSOLETE1(snd_pcm_hw_params_get_period_size_min, ALSA_0.9, ALSA_0.9.0rc4);
7261 OBSOLETE1(snd_pcm_hw_params_get_period_size_max, ALSA_0.9, ALSA_0.9.0rc4);
7262 OBSOLETE1(snd_pcm_hw_params_set_period_size_near, ALSA_0.9, ALSA_0.9.0rc4);
7263 OBSOLETE1(snd_pcm_hw_params_set_period_size_first, ALSA_0.9, ALSA_0.9.0rc4);
7264 OBSOLETE1(snd_pcm_hw_params_set_period_size_last, ALSA_0.9, ALSA_0.9.0rc4);
7266 OBSOLETE1(snd_pcm_hw_params_get_periods, ALSA_0.9, ALSA_0.9.0rc4);
7267 OBSOLETE1(snd_pcm_hw_params_get_periods_min, ALSA_0.9, ALSA_0.9.0rc4);
7268 OBSOLETE1(snd_pcm_hw_params_get_periods_max, ALSA_0.9, ALSA_0.9.0rc4);
7269 OBSOLETE1(snd_pcm_hw_params_set_periods_near, ALSA_0.9, ALSA_0.9.0rc4);
7270 OBSOLETE1(snd_pcm_hw_params_set_periods_first, ALSA_0.9, ALSA_0.9.0rc4);
7271 OBSOLETE1(snd_pcm_hw_params_set_periods_last, ALSA_0.9, ALSA_0.9.0rc4);
7273 OBSOLETE1(snd_pcm_hw_params_get_buffer_time, ALSA_0.9, ALSA_0.9.0rc4);
7274 OBSOLETE1(snd_pcm_hw_params_get_buffer_time_min, ALSA_0.9, ALSA_0.9.0rc4);
7275 OBSOLETE1(snd_pcm_hw_params_get_buffer_time_max, ALSA_0.9, ALSA_0.9.0rc4);
7276 OBSOLETE1(snd_pcm_hw_params_set_buffer_time_near, ALSA_0.9, ALSA_0.9.0rc4);
7277 OBSOLETE1(snd_pcm_hw_params_set_buffer_time_first, ALSA_0.9, ALSA_0.9.0rc4);
7278 OBSOLETE1(snd_pcm_hw_params_set_buffer_time_last, ALSA_0.9, ALSA_0.9.0rc4);
7280 OBSOLETE1(snd_pcm_hw_params_get_buffer_size, ALSA_0.9, ALSA_0.9.0rc4);
7281 OBSOLETE1(snd_pcm_hw_params_get_buffer_size_min, ALSA_0.9, ALSA_0.9.0rc4);
7282 OBSOLETE1(snd_pcm_hw_params_get_buffer_size_max, ALSA_0.9, ALSA_0.9.0rc4);
7283 OBSOLETE1(snd_pcm_hw_params_set_buffer_size_near, ALSA_0.9, ALSA_0.9.0rc4);
7284 OBSOLETE1(snd_pcm_hw_params_set_buffer_size_first, ALSA_0.9, ALSA_0.9.0rc4);
7285 OBSOLETE1(snd_pcm_hw_params_set_buffer_size_last, ALSA_0.9, ALSA_0.9.0rc4);
7287 OBSOLETE1(snd_pcm_hw_params_get_tick_time, ALSA_0.9, ALSA_0.9.0rc4);
7288 OBSOLETE1(snd_pcm_hw_params_get_tick_time_min, ALSA_0.9, ALSA_0.9.0rc4);
7289 OBSOLETE1(snd_pcm_hw_params_get_tick_time_max, ALSA_0.9, ALSA_0.9.0rc4);
7290 OBSOLETE1(snd_pcm_hw_params_set_tick_time_near, ALSA_0.9, ALSA_0.9.0rc4);
7291 OBSOLETE1(snd_pcm_hw_params_set_tick_time_first, ALSA_0.9, ALSA_0.9.0rc4);
7292 OBSOLETE1(snd_pcm_hw_params_set_tick_time_last, ALSA_0.9, ALSA_0.9.0rc4);
7294 OBSOLETE1(snd_pcm_sw_params_get_tstamp_mode, ALSA_0.9, ALSA_0.9.0rc4);
7295 OBSOLETE1(snd_pcm_sw_params_get_sleep_min, ALSA_0.9, ALSA_0.9.0rc4);
7296 OBSOLETE1(snd_pcm_sw_params_get_avail_min, ALSA_0.9, ALSA_0.9.0rc4);
7297 OBSOLETE1(snd_pcm_sw_params_get_xfer_align, ALSA_0.9, ALSA_0.9.0rc4);
7298 OBSOLETE1(snd_pcm_sw_params_get_start_threshold, ALSA_0.9, ALSA_0.9.0rc4);
7299 OBSOLETE1(snd_pcm_sw_params_get_stop_threshold, ALSA_0.9, ALSA_0.9.0rc4);
7300 OBSOLETE1(snd_pcm_sw_params_get_silence_threshold, ALSA_0.9, ALSA_0.9.0rc4);
7301 OBSOLETE1(snd_pcm_sw_params_get_silence_size, ALSA_0.9, ALSA_0.9.0rc4);
7303 #endif /* DOC_HIDDEN */
7306 * basic helpers
7311 * \brief Recover the stream state from an error or suspend
7312 * \param pcm PCM handle
7313 * \param err error number
7314 * \param silent do not print error reason
7315 * \return 0 when error code was handled successfuly, otherwise a negative error code
7317 * This a high-level helper function building on other functions.
7319 * This functions handles -EINTR (interrupted system call),
7320 * -EPIPE (overrun or underrun) and -ESTRPIPE (stream is suspended)
7321 * error codes trying to prepare given stream for next I/O.
7323 * Note that this function returs the original error code when it is not
7324 * handled inside this function (for example -EAGAIN is returned back).
7326 int snd_pcm_recover(snd_pcm_t *pcm, int err, int silent)
7328 if (err > 0)
7329 err = -err;
7330 if (err == -EINTR) /* nothing to do, continue */
7331 return 0;
7332 if (err == -EPIPE) {
7333 const char *s;
7334 if (snd_pcm_stream(pcm) == SND_PCM_STREAM_PLAYBACK)
7335 s = "underrun";
7336 else
7337 s = "overrun";
7338 if (!silent)
7339 SNDERR("%s occurred", s);
7340 err = snd_pcm_prepare(pcm);
7341 if (err < 0) {
7342 SNDERR("cannot recovery from %s, prepare failed: %s", s, snd_strerror(err));
7343 return err;
7345 return 0;
7347 if (err == -ESTRPIPE) {
7348 while ((err = snd_pcm_resume(pcm)) == -EAGAIN)
7349 /* wait until suspend flag is released */
7350 poll(NULL, 0, 1000);
7351 if (err < 0) {
7352 err = snd_pcm_prepare(pcm);
7353 if (err < 0) {
7354 SNDERR("cannot recovery from suspend, prepare failed: %s", snd_strerror(err));
7355 return err;
7358 return 0;
7360 return err;
7364 * \brief Set the hardware and software parameters in a simple way
7365 * \param pcm PCM handle
7366 * \param format required PCM format
7367 * \param access required PCM access
7368 * \param channels required PCM channels
7369 * \param rate required sample rate in Hz
7370 * \param soft_resample 0 = disallow alsa-lib resample stream, 1 = allow resampling
7371 * \param latency required overall latency in us
7372 * \return 0 on success otherwise a negative error code
7374 int snd_pcm_set_params(snd_pcm_t *pcm,
7375 snd_pcm_format_t format,
7376 snd_pcm_access_t access,
7377 unsigned int channels,
7378 unsigned int rate,
7379 int soft_resample,
7380 unsigned int latency)
7382 snd_pcm_hw_params_t *params;
7383 snd_pcm_sw_params_t *swparams;
7384 const char *s = snd_pcm_stream_name(snd_pcm_stream(pcm));
7385 snd_pcm_uframes_t buffer_size, period_size;
7386 unsigned int rrate, period_time;
7387 int err;
7389 snd_pcm_hw_params_alloca(&params);
7390 snd_pcm_sw_params_alloca(&swparams);
7392 assert(pcm);
7393 /* choose all parameters */
7394 err = snd_pcm_hw_params_any(pcm, params);
7395 if (err < 0) {
7396 SNDERR("Broken configuration for %s: no configurations available", s);
7397 return err;
7399 /* set software resampling */
7400 err = snd_pcm_hw_params_set_rate_resample(pcm, params, soft_resample);
7401 if (err < 0) {
7402 SNDERR("Resampling setup failed for %s: %s", s, snd_strerror(err));
7403 return err;
7405 /* set the selected read/write format */
7406 err = snd_pcm_hw_params_set_access(pcm, params, access);
7407 if (err < 0) {
7408 SNDERR("Access type not available for %s: %s", s, snd_strerror(err));
7409 return err;
7411 /* set the sample format */
7412 err = snd_pcm_hw_params_set_format(pcm, params, format);
7413 if (err < 0) {
7414 SNDERR("Sample format not available for %s: %s", s, snd_strerror(err));
7415 return err;
7417 /* set the count of channels */
7418 err = snd_pcm_hw_params_set_channels(pcm, params, channels);
7419 if (err < 0) {
7420 SNDERR("Channels count (%i) not available for %s: %s", channels, s, snd_strerror(err));
7421 return err;
7423 /* set the stream rate */
7424 rrate = rate;
7425 err = INTERNAL(snd_pcm_hw_params_set_rate_near)(pcm, params, &rrate, 0);
7426 if (err < 0) {
7427 SNDERR("Rate %iHz not available for playback: %s", rate, snd_strerror(err));
7428 return err;
7430 if (rrate != rate) {
7431 SNDERR("Rate doesn't match (requested %iHz, get %iHz)", rate, err);
7432 return -EINVAL;
7434 /* set the buffer time */
7435 err = INTERNAL(snd_pcm_hw_params_set_buffer_time_near)(pcm, params, &latency, NULL);
7436 if (err < 0) {
7437 /* error path -> set period size as first */
7438 /* set the period time */
7439 period_time = latency / 4;
7440 err = INTERNAL(snd_pcm_hw_params_set_period_time_near)(pcm, params, &period_time, NULL);
7441 if (err < 0) {
7442 SNDERR("Unable to set period time %i for %s: %s", period_time, s, snd_strerror(err));
7443 return err;
7445 err = INTERNAL(snd_pcm_hw_params_get_period_size)(params, &period_size, NULL);
7446 if (err < 0) {
7447 SNDERR("Unable to get period size for %s: %s", s, snd_strerror(err));
7448 return err;
7450 buffer_size = period_size * 4;
7451 err = INTERNAL(snd_pcm_hw_params_set_buffer_size_near)(pcm, params, &buffer_size);
7452 if (err < 0) {
7453 SNDERR("Unable to set buffer size %lu %s: %s", buffer_size, s, snd_strerror(err));
7454 return err;
7456 err = INTERNAL(snd_pcm_hw_params_get_buffer_size)(params, &buffer_size);
7457 if (err < 0) {
7458 SNDERR("Unable to get buffer size for %s: %s", s, snd_strerror(err));
7459 return err;
7461 } else {
7462 /* standard configuration buffer_time -> periods */
7463 err = INTERNAL(snd_pcm_hw_params_get_buffer_size)(params, &buffer_size);
7464 if (err < 0) {
7465 SNDERR("Unable to get buffer size for %s: %s", s, snd_strerror(err));
7466 return err;
7468 err = INTERNAL(snd_pcm_hw_params_get_buffer_time)(params, &latency, NULL);
7469 if (err < 0) {
7470 SNDERR("Unable to get buffer time (latency) for %s: %s", s, snd_strerror(err));
7471 return err;
7473 /* set the period time */
7474 period_time = latency / 4;
7475 err = INTERNAL(snd_pcm_hw_params_set_period_time_near)(pcm, params, &period_time, NULL);
7476 if (err < 0) {
7477 SNDERR("Unable to set period time %i for %s: %s", period_time, s, snd_strerror(err));
7478 return err;
7480 err = INTERNAL(snd_pcm_hw_params_get_period_size)(params, &period_size, NULL);
7481 if (err < 0) {
7482 SNDERR("Unable to get period size for %s: %s", s, snd_strerror(err));
7483 return err;
7486 /* write the parameters to device */
7487 err = snd_pcm_hw_params(pcm, params);
7488 if (err < 0) {
7489 SNDERR("Unable to set hw params for %s: %s", s, snd_strerror(err));
7490 return err;
7493 /* get the current swparams */
7494 err = snd_pcm_sw_params_current(pcm, swparams);
7495 if (err < 0) {
7496 SNDERR("Unable to determine current swparams for %s: %s", s, snd_strerror(err));
7497 return err;
7499 /* start the transfer when the buffer is almost full: */
7500 /* (buffer_size / avail_min) * avail_min */
7501 err = snd_pcm_sw_params_set_start_threshold(pcm, swparams, (buffer_size / period_size) * period_size);
7502 if (err < 0) {
7503 SNDERR("Unable to set start threshold mode for %s: %s", s, snd_strerror(err));
7504 return err;
7506 /* allow the transfer when at least period_size samples can be processed */
7507 err = snd_pcm_sw_params_set_avail_min(pcm, swparams, period_size);
7508 if (err < 0) {
7509 SNDERR("Unable to set avail min for %s: %s", s, snd_strerror(err));
7510 return err;
7512 /* write the parameters to the playback device */
7513 err = snd_pcm_sw_params(pcm, swparams);
7514 if (err < 0) {
7515 SNDERR("Unable to set sw params for %s: %s", s, snd_strerror(err));
7516 return err;
7518 return 0;
7522 * \brief Get the transfer size parameters in a simple way
7523 * \param pcm PCM handle
7524 * \param buffer_size PCM ring buffer size in frames
7525 * \param period_size PCM period size in frames
7526 * \return 0 on success otherwise a negative error code
7528 int snd_pcm_get_params(snd_pcm_t *pcm,
7529 snd_pcm_uframes_t *buffer_size,
7530 snd_pcm_uframes_t *period_size)
7532 snd_pcm_hw_params_t *hw;
7533 int err;
7535 assert(pcm);
7536 snd_pcm_hw_params_alloca(&hw);
7537 err = snd_pcm_hw_params_current(pcm, hw);
7538 if (err < 0)
7539 return err;
7540 err = INTERNAL(snd_pcm_hw_params_get_buffer_size)(hw, buffer_size);
7541 if (err < 0)
7542 return err;
7543 err = INTERNAL(snd_pcm_hw_params_get_period_size)(hw, period_size, NULL);
7544 if (err < 0)
7545 return err;
7546 return 0;