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