source: roaraudio/libroarpulse/stream.c @ 3427:bb188ddb4b1d

Last change on this file since 3427:bb188ddb4b1d was 3427:bb188ddb4b1d, checked in by phi, 14 years ago

support pa_stream_get_sample_spec()

File size: 13.2 KB
Line 
1//stream.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010
5 *  The code (may) include prototypes and comments (and maybe
6 *  other code fragements) from libpulse*. They are mostly copyrighted by:
7 *  Lennart Poettering <poettering@users.sourceforge.net> and
8 *  Pierre Ossman <drzeus@drzeus.cx>
9 *
10 *  This file is part of libroarpulse a part of RoarAudio,
11 *  a cross-platform sound system for both, home and professional use.
12 *  See README for details.
13 *
14 *  This file is free software; you can redistribute it and/or modify
15 *  it under the terms of the GNU General Public License version 3
16 *  as published by the Free Software Foundation.
17 *
18 *  RoarAudio is distributed in the hope that it will be useful,
19 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
20 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 *  GNU General Public License for more details.
22 *
23 *  You should have received a copy of the GNU General Public License
24 *  along with this software; see the file COPYING.  If not, write to
25 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
26 *
27 *  NOTE for everyone want's to change something and send patches:
28 *  read README and HACKING! There a addition information on
29 *  the license of this document you need to read before you send
30 *  any patches.
31 *
32 *  NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc
33 *  or libpulse*:
34 *  The libs libroaresd, libroararts and libroarpulse link this libroar
35 *  and are therefore GPL. Because of this it may be illigal to use
36 *  them with any software that uses libesd, libartsc or libpulse*.
37 */
38
39#include <libroarpulse/libroarpulse.h>
40
41struct pa_stream {
42 size_t refc;
43 pa_context * c;
44 struct roar_vio_calls vio;
45 struct roar_stream stream;
46 pa_stream_state_t state;
47 pa_sample_spec    sspec;
48 struct {
49  pa_stream_notify_cb_t   change_state;
50  void                  * change_state_ud;
51 } cb;
52};
53
54typedef void pa_proplist;
55void pa_stream_set_state(pa_stream *s, pa_stream_state_t st);
56
57pa_stream* pa_stream_new_with_proplist(
58        pa_context *c                     ,
59        const char *name                  ,
60        const pa_sample_spec *ss          ,
61        const pa_channel_map *map         ,
62        pa_proplist *p                    );
63
64/** Create a new, unconnected stream with the specified name and sample type */
65pa_stream* pa_stream_new(
66        pa_context *c                     /**< The context to create this stream in */,
67        const char *name                  /**< A name for this stream */,
68        const pa_sample_spec *ss          /**< The desired sample format */,
69        const pa_channel_map *map         /**< The desired channel map, or NULL for default */) {
70 return pa_stream_new_with_proplist(c, name, ss, map, NULL);
71}
72
73pa_stream* pa_stream_new_with_proplist(
74        pa_context *c                     ,
75        const char *name                  ,
76        const pa_sample_spec *ss          ,
77        const pa_channel_map *map         ,
78        pa_proplist *p                    ) {
79 pa_stream * s;
80
81 if ( p != NULL )
82  return NULL;
83
84 if ( (s = roar_mm_malloc(sizeof(pa_stream))) == NULL )
85  return NULL;
86
87 memset(s, 0, sizeof(pa_stream));
88
89 memcpy(&(s->sspec), ss, sizeof(pa_sample_spec));
90
91 if ( roar_pa_sspec2auinfo(&(s->stream.info), ss) == -1 ) {
92  roar_mm_free(s);
93  return NULL;
94 }
95
96 s->state = PA_STREAM_UNCONNECTED;
97 s->c     = c;
98 pa_context_ref(c);
99
100 return s;
101}
102
103static void _pa_stream_free(pa_stream * s) {
104 pa_stream_disconnect(s);
105 pa_context_unref(s->c);
106 roar_mm_free(s);
107}
108
109/** Decrease the reference counter by one */
110void pa_stream_unref(pa_stream *s) {
111 if ( s == NULL )
112  return;
113
114 s->refc--;
115
116 if (s->refc < 1 )
117  _pa_stream_free(s);
118}
119
120/** Increase the reference counter by one */
121pa_stream *pa_stream_ref(pa_stream *s) {
122 if ( s == NULL )
123  return NULL;
124
125 s->refc++;
126
127 return s;
128}
129
130/** Return the current state of the stream */
131pa_stream_state_t pa_stream_get_state(pa_stream *p) {
132 if ( p == NULL )
133  return PA_STREAM_FAILED;
134
135 return p->state;
136}
137
138/** Return the context this stream is attached to */
139pa_context* pa_stream_get_context(pa_stream *p) {
140 if ( p == NULL )
141  return NULL;
142
143 return p->c;
144}
145
146/** Return the device (sink input or source output) index this stream is connected to */
147uint32_t pa_stream_get_index(pa_stream *s) {
148 return 0;
149}
150
151/** Connect the stream to a sink */
152int pa_stream_connect_playback(
153        pa_stream *s                  /**< The stream to connect to a sink */,
154        const char *dev               /**< Name of the sink to connect to, or NULL for default */ ,
155        const pa_buffer_attr *attr    /**< Buffering attributes, or NULL for default */,
156        pa_stream_flags_t flags       /**< Additional flags, or 0 for default */,
157        pa_cvolume *volume            /**< Initial volume, or NULL for default */,
158        pa_stream *sync_stream        /**< Synchronize this stream with the specified one, or NULL for a standalone stream*/);
159
160/** Connect the stream to a source */
161int pa_stream_connect_record(
162        pa_stream *s                  /**< The stream to connect to a source */ ,
163        const char *dev               /**< Name of the source to connect to, or NULL for default */,
164        const pa_buffer_attr *attr    /**< Buffer attributes, or NULL for default */,
165        pa_stream_flags_t flags       /**< Additional flags, or 0 for default */);
166
167/** Disconnect a stream from a source/sink */
168int pa_stream_disconnect(pa_stream *s) {
169 if ( s == NULL )
170  return -1;
171
172 if ( s->state != PA_STREAM_READY )
173  return -1;
174
175 roar_vio_close(&(s->vio));
176
177 pa_stream_set_state(s, PA_STREAM_TERMINATED);
178
179 return 0;
180}
181
182/** Write some data to the server (for playback sinks), if free_cb is
183 * non-NULL this routine is called when all data has been written out
184 * and an internal reference to the specified data is kept, the data
185 * is not copied. If NULL, the data is copied into an internal
186 * buffer. The client my freely seek around in the output buffer. For
187 * most applications passing 0 and PA_SEEK_RELATIVE as arguments for
188 * offset and seek should be useful.*/
189int pa_stream_write(
190        pa_stream *p             /**< The stream to use */,
191        const void *data         /**< The data to write */,
192        size_t length            /**< The length of the data to write */,
193        pa_free_cb_t free_cb     /**< A cleanup routine for the data or NULL to request an internal copy */,
194        int64_t offset,          /**< Offset for seeking, must be 0 for upload streams */
195        pa_seek_mode_t seek      /**< Seek mode, must be PA_SEEK_RELATIVE for upload streams */);
196
197/** Read the next fragment from the buffer (for recording).
198 * data will point to the actual data and length will contain the size
199 * of the data in bytes (which can be less than a complete framgnet).
200 * Use pa_stream_drop() to actually remove the data from the
201 * buffer. If no data is available will return a NULL pointer  \since 0.8 */
202int pa_stream_peek(
203        pa_stream *p                 /**< The stream to use */,
204        const void **data            /**< Pointer to pointer that will point to data */,
205        size_t *length              /**< The length of the data read */);
206
207/** Remove the current fragment on record streams. It is invalid to do this without first
208 * calling pa_stream_peek(). \since 0.8 */
209int pa_stream_drop(pa_stream *p);
210
211/** Return the nember of bytes that may be written using pa_stream_write() */
212size_t pa_stream_writable_size(pa_stream *p);
213
214/** Return the number of bytes that may be read using pa_stream_read() \since 0.8 */
215size_t pa_stream_readable_size(pa_stream *p);
216
217/** Drain a playback stream. Use this for notification when the buffer is empty */
218pa_operation* pa_stream_drain(pa_stream *s, pa_stream_success_cb_t cb, void *userdata);
219
220/** Request a timing info structure update for a stream. Use
221 * pa_stream_get_timing_info() to get access to the raw timing data,
222 * or pa_stream_get_time() or pa_stream_get_latency() to get cleaned
223 * up values. */
224pa_operation* pa_stream_update_timing_info(pa_stream *p, pa_stream_success_cb_t cb, void *userdata);
225
226/** Set the callback function that is called whenever the state of the stream changes */
227void pa_stream_set_state_callback(pa_stream *s, pa_stream_notify_cb_t cb, void *userdata) {
228 if ( s == NULL )
229  return;
230
231 s->cb.change_state    = cb;
232 s->cb.change_state_ud = userdata;
233}
234
235void pa_stream_set_state(pa_stream *s, pa_stream_state_t st) {
236 if ( s == NULL )
237  return;
238
239 s->state = st;
240
241 if ( s->cb.change_state == NULL ) {
242  s->cb.change_state(s, s->cb.change_state_ud);
243 }
244}
245
246/** Set the callback function that is called when new data may be
247 * written to the stream. */
248void pa_stream_set_write_callback(pa_stream *p, pa_stream_request_cb_t cb, void *userdata);
249
250/** Set the callback function that is called when new data is available from the stream.
251 * Return the number of bytes read. \since 0.8 */
252void pa_stream_set_read_callback(pa_stream *p, pa_stream_request_cb_t cb, void *userdata);
253
254/** Set the callback function that is called when a buffer overflow happens. (Only for playback streams) \since 0.8 */
255void pa_stream_set_overflow_callback(pa_stream *p, pa_stream_notify_cb_t cb, void *userdata);
256
257/** Set the callback function that is called when a buffer underflow happens. (Only for playback streams) \since 0.8 */
258void pa_stream_set_underflow_callback(pa_stream *p, pa_stream_notify_cb_t cb, void *userdata);
259
260/** Set the callback function that is called whenever a latency information update happens. Useful on PA_STREAM_AUTO_TIMING_UPDATE streams only. (Only for playback streams) \since 0.8.2 */
261void pa_stream_set_latency_update_callback(pa_stream *p, pa_stream_notify_cb_t cb, void *userdata);
262
263/** Pause (or resume) playback of this stream temporarily. Available on both playback and recording streams. \since 0.3 */
264pa_operation* pa_stream_cork(pa_stream *s, int b, pa_stream_success_cb_t cb, void *userdata);
265
266/** Flush the playback buffer of this stream. Most of the time you're
267 * better off using the parameter delta of pa_stream_write() instead of this
268 * function. Available on both playback and recording streams. \since 0.3 */
269pa_operation* pa_stream_flush(pa_stream *s, pa_stream_success_cb_t cb, void *userdata);
270/** Reenable prebuffering as specified in the pa_buffer_attr
271 * structure. Available for playback streams only. \since 0.6 */
272pa_operation* pa_stream_prebuf(pa_stream *s, pa_stream_success_cb_t cb, void *userdata);
273
274/** Request immediate start of playback on this stream. This disables
275 * prebuffering as specified in the pa_buffer_attr
276 * structure, temporarily. Available for playback streams only. \since 0.3 */
277pa_operation* pa_stream_trigger(pa_stream *s, pa_stream_success_cb_t cb, void *userdata);
278
279/** Rename the stream. \since 0.5 */
280pa_operation* pa_stream_set_name(pa_stream *s, const char *name, pa_stream_success_cb_t cb, void *userdata);
281
282/** Return the current playback/recording time. This is based on the
283 * data in the timing info structure returned by
284 * pa_stream_get_timing_info(). This function will usually only return
285 * new data if a timing info update has been recieved. Only if timing
286 * interpolation has been requested (PA_STREAM_INTERPOLATE_TIMING)
287 * the data from the last timing update is used for an estimation of
288 * the current playback/recording time based on the local time that
289 * passed since the timing info structure has been acquired. The time
290 * value returned by this function is guaranteed to increase
291 * monotonically. (that means: the returned value is always greater or
292 * equal to the value returned on the last call) This behaviour can
293 * be disabled by using PA_STREAM_NOT_MONOTONOUS. This may be
294 * desirable to deal better with bad estimations of transport
295 * latencies, but may have strange effects if the application is not
296 * able to deal with time going 'backwards'. \since 0.6 */
297int pa_stream_get_time(pa_stream *s, pa_usec_t *r_usec);
298
299/** Return the total stream latency. This function is based on
300 * pa_stream_get_time(). In case the stream is a monitoring stream the
301 * result can be negative, i.e. the captured samples are not yet
302 * played. In this case *negative is set to 1. \since 0.6 */
303int pa_stream_get_latency(pa_stream *s, pa_usec_t *r_usec, int *negative);
304
305/** Return the latest raw timing data structure. The returned pointer
306 * points to an internal read-only instance of the timing
307 * structure. The user should make a copy of this structure if he
308 * wants to modify it. An in-place update to this data structure may
309 * be requested using pa_stream_update_timing_info(). If no
310 * pa_stream_update_timing_info() call was issued before, this
311 * function will fail with PA_ERR_NODATA. Please note that the
312 * write_index member field (and only this field) is updated on each
313 * pa_stream_write() call, not just when a timing update has been
314 * recieved. \since 0.8 */
315const pa_timing_info* pa_stream_get_timing_info(pa_stream *s);
316
317/** Return a pointer to the stream's sample specification. \since 0.6 */
318const pa_sample_spec* pa_stream_get_sample_spec(pa_stream *s) {
319 if ( s == NULL )
320  return NULL;
321
322 return &(s->sspec);
323}
324
325/** Return a pointer to the stream's channel map. \since 0.8 */
326const pa_channel_map* pa_stream_get_channel_map(pa_stream *s);
327
328/** Return the buffer metrics of the stream. Only valid after the
329 * stream has been connected successfuly and if the server is at least
330 * PulseAudio 0.9. \since 0.9.0 */
331const pa_buffer_attr* pa_stream_get_buffer_attr(pa_stream *s);
332
333//ll
Note: See TracBrowser for help on using the repository browser.