1 /* pcm.h
2 **
3 ** Copyright 2011, The Android Open Source Project
4 **
5 ** Redistribution and use in source and binary forms, with or without
6 ** modification, are permitted provided that the following conditions are met:
7 **     * Redistributions of source code must retain the above copyright
8 **       notice, this list of conditions and the following disclaimer.
9 **     * Redistributions in binary form must reproduce the above copyright
10 **       notice, this list of conditions and the following disclaimer in the
11 **       documentation and/or other materials provided with the distribution.
12 **     * Neither the name of The Android Open Source Project nor the names of
13 **       its contributors may be used to endorse or promote products derived
14 **       from this software without specific prior written permission.
15 **
16 ** THIS SOFTWARE IS PROVIDED BY The Android Open Source Project ``AS IS'' AND
17 ** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 ** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 ** ARE DISCLAIMED. IN NO EVENT SHALL The Android Open Source Project BE LIABLE
20 ** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 ** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 ** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23 ** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 ** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 ** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
26 ** DAMAGE.
27 */
28 
29 /** @file */
30 
31 /** @defgroup libtinyalsa-pcm PCM Interface
32  * @brief All macros, structures and functions that make up the PCM interface.
33  */
34 
35 #ifndef TINYALSA_PCM_H
36 #define TINYALSA_PCM_H
37 
38 #include <tinyalsa/attributes.h>
39 
40 #include <sys/time.h>
41 #include <stddef.h>
42 
43 /** A flag that specifies that the PCM is an output.
44  * May not be bitwise AND'd with @ref PCM_IN.
45  * Used in @ref pcm_open.
46  * @ingroup libtinyalsa-pcm
47  */
48 #define PCM_OUT 0x00000000
49 
50 /** Specifies that the PCM is an input.
51  * May not be bitwise AND'd with @ref PCM_OUT.
52  * Used in @ref pcm_open.
53  * @ingroup libtinyalsa-pcm
54  */
55 #define PCM_IN 0x10000000
56 
57 /** Specifies that the PCM will use mmap read and write methods.
58  * Used in @ref pcm_open.
59  * @ingroup libtinyalsa-pcm
60  */
61 #define PCM_MMAP 0x00000001
62 
63 /** Specifies no interrupt requests.
64  * May only be bitwise AND'd with @ref PCM_MMAP.
65  * Used in @ref pcm_open.
66  * @ingroup libtinyalsa-pcm
67  */
68 #define PCM_NOIRQ 0x00000002
69 
70 /** When set, calls to @ref pcm_write
71  * for a playback stream will not attempt
72  * to restart the stream in the case of an
73  * underflow, but will return -EPIPE instead.
74  * After the first -EPIPE error, the stream
75  * is considered to be stopped, and a second
76  * call to pcm_write will attempt to restart
77  * the stream.
78  * Used in @ref pcm_open.
79  * @ingroup libtinyalsa-pcm
80  */
81 #define PCM_NORESTART 0x00000004
82 
83 /** Specifies monotonic timestamps.
84  * Used in @ref pcm_open.
85  * @ingroup libtinyalsa-pcm
86  */
87 #define PCM_MONOTONIC 0x00000008
88 
89 /** If used with @ref pcm_open and @ref pcm_params_get,
90  * it will not cause the function to block if
91  * the PCM is not available. It will also cause
92  * the functions @ref pcm_readi and @ref pcm_writei
93  * to exit if they would cause the caller to wait.
94  * @ingroup libtinyalsa-pcm
95  * */
96 #define PCM_NONBLOCK 0x00000010
97 
98 /** Means a PCM is opened
99  * @ingroup libtinyalsa-pcm
100  */
101 #define PCM_STATE_OPEN 0x00
102 
103 /** Means a PCM HW_PARAMS is set
104  * @ingroup libtinyalsa-pcm
105  */
106 #define PCM_STATE_SETUP 0x01
107 
108 /** Means a PCM is prepared
109  * @ingroup libtinyalsa-pcm
110  */
111 #define PCM_STATE_PREPARED 0x02
112 
113 /** For inputs, this means the PCM is recording audio samples.
114  * For outputs, this means the PCM is playing audio samples.
115  * @ingroup libtinyalsa-pcm
116  */
117 #define PCM_STATE_RUNNING 0x03
118 
119 /** For inputs, this means an overrun occured.
120  * For outputs, this means an underrun occured.
121  */
122 #define PCM_STATE_XRUN 0x04
123 
124 /** For outputs, this means audio samples are played.
125  * A PCM is in a draining state when it is coming to a stop.
126  */
127 #define PCM_STATE_DRAINING 0x05
128 
129 /** Means a PCM is suspended.
130  * @ingroup libtinyalsa-pcm
131  */
132 #define PCM_STATE_SUSPENDED 0x07
133 
134 /** Means a PCM has been disconnected.
135  * @ingroup libtinyalsa-pcm
136  */
137 #define PCM_STATE_DISCONNECTED 0x08
138 
139 #if defined(__cplusplus)
140 extern "C" {
141 #endif
142 
143 /** Audio sample format of a PCM.
144  * The first letter specifiers whether the sample is signed or unsigned.
145  * The letter 'S' means signed. The letter 'U' means unsigned.
146  * The following number is the amount of bits that the sample occupies in memory.
147  * Following the underscore, specifiers whether the sample is big endian or little endian.
148  * The letters 'LE' mean little endian.
149  * The letters 'BE' mean big endian.
150  * This enumeration is used in the @ref pcm_config structure.
151  * @ingroup libtinyalsa-pcm
152  */
153 enum pcm_format {
154 
155 /* Note: This section must stay in the same
156  * order for binary compatibility with older
157  * versions of TinyALSA. */
158 
159     PCM_FORMAT_INVALID = -1,
160     /** Signed 16-bit, little endian */
161     PCM_FORMAT_S16_LE = 0,
162     /** Signed, 32-bit, little endian */
163     PCM_FORMAT_S32_LE,
164     /** Signed, 8-bit */
165     PCM_FORMAT_S8,
166     /** Signed, 24-bit (32-bit in memory), little endian */
167     PCM_FORMAT_S24_LE,
168     /** Signed, 24-bit, little endian */
169     PCM_FORMAT_S24_3LE,
170 
171 /* End of compatibility section. */
172 
173     /** Signed, 16-bit, big endian */
174     PCM_FORMAT_S16_BE,
175     /** Signed, 24-bit (32-bit in memory), big endian */
176     PCM_FORMAT_S24_BE,
177     /** Signed, 24-bit, big endian */
178     PCM_FORMAT_S24_3BE,
179     /** Signed, 32-bit, big endian */
180     PCM_FORMAT_S32_BE,
181     /** 32-bit float, little endian */
182     PCM_FORMAT_FLOAT_LE,
183     /** 32-bit float, big endian */
184     PCM_FORMAT_FLOAT_BE,
185     /** Max of the enumeration list, not an actual format. */
186     PCM_FORMAT_MAX
187 };
188 
189 /** A bit mask of 256 bits (32 bytes) that describes some hardware parameters of a PCM */
190 struct pcm_mask {
191     /** bits of the bit mask */
192     unsigned int bits[32 / sizeof(unsigned int)];
193 };
194 
195 /** Encapsulates the hardware and software parameters of a PCM.
196  * @ingroup libtinyalsa-pcm
197  */
198 struct pcm_config {
199     /** The number of channels in a frame */
200     unsigned int channels;
201     /** The number of frames per second */
202     unsigned int rate;
203     /** The number of frames in a period */
204     unsigned int period_size;
205     /** The number of periods in a PCM */
206     unsigned int period_count;
207     /** The sample format of a PCM */
208     enum pcm_format format;
209     /* Values to use for the ALSA start, stop and silence thresholds, and
210      * silence size.  Setting any one of these values to 0 will cause the
211      * default tinyalsa values to be used instead.
212      * Tinyalsa defaults are as follows.
213      *
214      * start_threshold   : period_count * period_size
215      * stop_threshold    : period_count * period_size
216      * silence_threshold : 0
217      * silence_size      : 0
218      */
219     /** The minimum number of frames required to start the PCM */
220     unsigned int start_threshold;
221     /** The minimum number of frames required to stop the PCM */
222     unsigned int stop_threshold;
223     /** The minimum number of frames to silence the PCM */
224     unsigned int silence_threshold;
225     /** The number of frames to overwrite the playback buffer when the playback underrun is greater
226      * than the silence threshold */
227     unsigned int silence_size;
228 
229     unsigned int avail_min;
230 };
231 
232 /** Enumeration of a PCM's hardware parameters.
233  * Each of these parameters is either a mask or an interval.
234  * @ingroup libtinyalsa-pcm
235  */
236 enum pcm_param
237 {
238     /** A mask that represents the type of read or write method available (e.g. interleaved, mmap). */
239     PCM_PARAM_ACCESS,
240     /** A mask that represents the @ref pcm_format available (e.g. @ref PCM_FORMAT_S32_LE) */
241     PCM_PARAM_FORMAT,
242     /** A mask that represents the subformat available */
243     PCM_PARAM_SUBFORMAT,
244     /** An interval representing the range of sample bits available (e.g. 8 to 32) */
245     PCM_PARAM_SAMPLE_BITS,
246     /** An interval representing the range of frame bits available (e.g. 8 to 64) */
247     PCM_PARAM_FRAME_BITS,
248     /** An interval representing the range of channels available (e.g. 1 to 2) */
249     PCM_PARAM_CHANNELS,
250     /** An interval representing the range of rates available (e.g. 44100 to 192000) */
251     PCM_PARAM_RATE,
252     PCM_PARAM_PERIOD_TIME,
253     /** The number of frames in a period */
254     PCM_PARAM_PERIOD_SIZE,
255     /** The number of bytes in a period */
256     PCM_PARAM_PERIOD_BYTES,
257     /** The number of periods for a PCM */
258     PCM_PARAM_PERIODS,
259     PCM_PARAM_BUFFER_TIME,
260     PCM_PARAM_BUFFER_SIZE,
261     PCM_PARAM_BUFFER_BYTES,
262     PCM_PARAM_TICK_TIME,
263 }; /* enum pcm_param */
264 
265 struct pcm_params;
266 
267 struct pcm_params *pcm_params_get(unsigned int card, unsigned int device,
268                                   unsigned int flags);
269 
270 void pcm_params_free(struct pcm_params *pcm_params);
271 
272 const struct pcm_mask *pcm_params_get_mask(const struct pcm_params *pcm_params, enum pcm_param param);
273 
274 unsigned int pcm_params_get_min(const struct pcm_params *pcm_params, enum pcm_param param);
275 
276 unsigned int pcm_params_get_max(const struct pcm_params *pcm_params, enum pcm_param param);
277 
278 /* Converts the pcm parameters to a human readable string.
279  * The string parameter is a caller allocated buffer of size bytes,
280  * which is then filled up to size - 1 and null terminated,
281  * if size is greater than zero.
282  * The return value is the number of bytes copied to string
283  * (not including null termination) if less than size; otherwise,
284  * the number of bytes required for the buffer.
285  */
286 int pcm_params_to_string(struct pcm_params *params, char *string, unsigned int size);
287 
288 /* Returns 1 if the pcm_format is present (format bit set) in
289  * the pcm_params structure; 0 otherwise, or upon unrecognized format.
290  */
291 int pcm_params_format_test(struct pcm_params *params, enum pcm_format format);
292 
293 struct pcm;
294 
295 struct pcm *pcm_open(unsigned int card,
296                      unsigned int device,
297                      unsigned int flags,
298                      const struct pcm_config *config);
299 
300 struct pcm *pcm_open_by_name(const char *name,
301                              unsigned int flags,
302                              const struct pcm_config *config);
303 
304 int pcm_close(struct pcm *pcm);
305 
306 int pcm_is_ready(const struct pcm *pcm);
307 
308 unsigned int pcm_get_channels(const struct pcm *pcm);
309 
310 const struct pcm_config * pcm_get_config(const struct pcm *pcm);
311 
312 unsigned int pcm_get_rate(const struct pcm *pcm);
313 
314 enum pcm_format pcm_get_format(const struct pcm *pcm);
315 
316 int pcm_get_file_descriptor(const struct pcm *pcm);
317 
318 const char *pcm_get_error(const struct pcm *pcm);
319 
320 int pcm_set_config(struct pcm *pcm, const struct pcm_config *config);
321 
322 unsigned int pcm_format_to_bits(enum pcm_format format);
323 
324 unsigned int pcm_get_buffer_size(const struct pcm *pcm);
325 
326 unsigned int pcm_frames_to_bytes(const struct pcm *pcm, unsigned int frames);
327 
328 unsigned int pcm_bytes_to_frames(const struct pcm *pcm, unsigned int bytes);
329 
330 int pcm_get_htimestamp(struct pcm *pcm, unsigned int *avail, struct timespec *tstamp);
331 
332 unsigned int pcm_get_subdevice(const struct pcm *pcm);
333 
334 int pcm_writei(struct pcm *pcm, const void *data, unsigned int frame_count) TINYALSA_WARN_UNUSED_RESULT;
335 
336 int pcm_readi(struct pcm *pcm, void *data, unsigned int frame_count) TINYALSA_WARN_UNUSED_RESULT;
337 
338 int pcm_write(struct pcm *pcm, const void *data, unsigned int count) TINYALSA_DEPRECATED;
339 
340 int pcm_read(struct pcm *pcm, void *data, unsigned int count) TINYALSA_DEPRECATED;
341 
342 int pcm_mmap_write(struct pcm *pcm, const void *data, unsigned int count) TINYALSA_DEPRECATED;
343 
344 int pcm_mmap_read(struct pcm *pcm, void *data, unsigned int count) TINYALSA_DEPRECATED;
345 
346 int pcm_mmap_begin(struct pcm *pcm, void **areas, unsigned int *offset, unsigned int *frames);
347 
348 int pcm_mmap_commit(struct pcm *pcm, unsigned int offset, unsigned int frames);
349 
350 int pcm_mmap_avail(struct pcm *pcm);
351 
352 int pcm_mmap_get_hw_ptr(struct pcm* pcm, unsigned int *hw_ptr, struct timespec *tstamp);
353 
354 int pcm_get_poll_fd(struct pcm *pcm);
355 
356 int pcm_link(struct pcm *pcm1, struct pcm *pcm2);
357 
358 int pcm_unlink(struct pcm *pcm);
359 
360 int pcm_prepare(struct pcm *pcm);
361 
362 int pcm_start(struct pcm *pcm);
363 
364 int pcm_stop(struct pcm *pcm);
365 
366 int pcm_wait(struct pcm *pcm, int timeout);
367 
368 long pcm_get_delay(struct pcm *pcm);
369 
370 int pcm_ioctl(struct pcm *pcm, int code, ...) TINYALSA_DEPRECATED;
371 
372 #if defined(__cplusplus)
373 }  /* extern "C" */
374 #endif
375 
376 #endif
377 
378