Remove unnecessary #includes
[profile/ivi/pulseaudio.git] / src / pulse / simple.c
1
2 /***
3   This file is part of PulseAudio.
4
5   Copyright 2004-2006 Lennart Poettering
6
7   PulseAudio is free software; you can redistribute it and/or modify
8   it under the terms of the GNU Lesser General Public License as published
9   by the Free Software Foundation; either version 2.1 of the License,
10   or (at your option) any later version.
11
12   PulseAudio is distributed in the hope that it will be useful, but
13   WITHOUT ANY WARRANTY; without even the implied warranty of
14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15   General Public License for more details.
16
17   You should have received a copy of the GNU Lesser General Public License
18   along with PulseAudio; if not, write to the Free Software
19   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20   USA.
21 ***/
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include <stdio.h>
28 #include <string.h>
29 #include <stdlib.h>
30
31 #include <pulse/pulseaudio.h>
32 #include <pulse/thread-mainloop.h>
33 #include <pulse/xmalloc.h>
34
35 #include <pulsecore/log.h>
36 #include <pulsecore/macro.h>
37
38 #include "simple.h"
39
40 struct pa_simple {
41     pa_threaded_mainloop *mainloop;
42     pa_context *context;
43     pa_stream *stream;
44     pa_stream_direction_t direction;
45
46     const void *read_data;
47     size_t read_index, read_length;
48
49     int operation_success;
50 };
51
52 #define CHECK_VALIDITY_RETURN_ANY(rerror, expression, error, ret)       \
53     do {                                                                \
54         if (!(expression)) {                                            \
55             if (rerror)                                                 \
56                 *(rerror) = error;                                      \
57             return (ret);                                               \
58         }                                                               \
59     } while(FALSE);
60
61 #define CHECK_SUCCESS_GOTO(p, rerror, expression, label)        \
62     do {                                                        \
63         if (!(expression)) {                                    \
64             if (rerror)                                         \
65                 *(rerror) = pa_context_errno((p)->context);     \
66             goto label;                                         \
67         }                                                       \
68     } while(FALSE);
69
70 #define CHECK_DEAD_GOTO(p, rerror, label)                               \
71     do {                                                                \
72         if (!(p)->context || !PA_CONTEXT_IS_GOOD(pa_context_get_state((p)->context)) || \
73             !(p)->stream || !PA_STREAM_IS_GOOD(pa_stream_get_state((p)->stream))) { \
74             if (((p)->context && pa_context_get_state((p)->context) == PA_CONTEXT_FAILED) || \
75                 ((p)->stream && pa_stream_get_state((p)->stream) == PA_STREAM_FAILED)) { \
76                 if (rerror)                                             \
77                     *(rerror) = pa_context_errno((p)->context);         \
78             } else                                                      \
79                 if (rerror)                                             \
80                     *(rerror) = PA_ERR_BADSTATE;                        \
81             goto label;                                                 \
82         }                                                               \
83     } while(FALSE);
84
85 static void context_state_cb(pa_context *c, void *userdata) {
86     pa_simple *p = userdata;
87     pa_assert(c);
88     pa_assert(p);
89
90     switch (pa_context_get_state(c)) {
91         case PA_CONTEXT_READY:
92         case PA_CONTEXT_TERMINATED:
93         case PA_CONTEXT_FAILED:
94             pa_threaded_mainloop_signal(p->mainloop, 0);
95             break;
96
97         case PA_CONTEXT_UNCONNECTED:
98         case PA_CONTEXT_CONNECTING:
99         case PA_CONTEXT_AUTHORIZING:
100         case PA_CONTEXT_SETTING_NAME:
101             break;
102     }
103 }
104
105 static void stream_state_cb(pa_stream *s, void * userdata) {
106     pa_simple *p = userdata;
107     pa_assert(s);
108     pa_assert(p);
109
110     switch (pa_stream_get_state(s)) {
111
112         case PA_STREAM_READY:
113         case PA_STREAM_FAILED:
114         case PA_STREAM_TERMINATED:
115             pa_threaded_mainloop_signal(p->mainloop, 0);
116             break;
117
118         case PA_STREAM_UNCONNECTED:
119         case PA_STREAM_CREATING:
120             break;
121     }
122 }
123
124 static void stream_request_cb(pa_stream *s, size_t length, void *userdata) {
125     pa_simple *p = userdata;
126     pa_assert(p);
127
128     pa_threaded_mainloop_signal(p->mainloop, 0);
129 }
130
131 static void stream_latency_update_cb(pa_stream *s, void *userdata) {
132     pa_simple *p = userdata;
133
134     pa_assert(p);
135
136     pa_threaded_mainloop_signal(p->mainloop, 0);
137 }
138
139 pa_simple* pa_simple_new(
140         const char *server,
141         const char *name,
142         pa_stream_direction_t dir,
143         const char *dev,
144         const char *stream_name,
145         const pa_sample_spec *ss,
146         const pa_channel_map *map,
147         const pa_buffer_attr *attr,
148         int *rerror) {
149
150     pa_simple *p;
151     int error = PA_ERR_INTERNAL, r;
152
153     CHECK_VALIDITY_RETURN_ANY(rerror, !server || *server, PA_ERR_INVALID, NULL);
154     CHECK_VALIDITY_RETURN_ANY(rerror, dir == PA_STREAM_PLAYBACK || dir == PA_STREAM_RECORD, PA_ERR_INVALID, NULL);
155     CHECK_VALIDITY_RETURN_ANY(rerror, !dev || *dev, PA_ERR_INVALID, NULL);
156     CHECK_VALIDITY_RETURN_ANY(rerror, ss && pa_sample_spec_valid(ss), PA_ERR_INVALID, NULL);
157     CHECK_VALIDITY_RETURN_ANY(rerror, !map || (pa_channel_map_valid(map) && map->channels == ss->channels), PA_ERR_INVALID, NULL)
158
159     p = pa_xnew0(pa_simple, 1);
160     p->direction = dir;
161
162     if (!(p->mainloop = pa_threaded_mainloop_new()))
163         goto fail;
164
165     if (!(p->context = pa_context_new(pa_threaded_mainloop_get_api(p->mainloop), name)))
166         goto fail;
167
168     pa_context_set_state_callback(p->context, context_state_cb, p);
169
170     if (pa_context_connect(p->context, server, 0, NULL) < 0) {
171         error = pa_context_errno(p->context);
172         goto fail;
173     }
174
175     pa_threaded_mainloop_lock(p->mainloop);
176
177     if (pa_threaded_mainloop_start(p->mainloop) < 0)
178         goto unlock_and_fail;
179
180     for (;;) {
181         pa_context_state_t state;
182
183         state = pa_context_get_state(p->context);
184
185         if (state == PA_CONTEXT_READY)
186             break;
187
188         if (!PA_CONTEXT_IS_GOOD(state)) {
189             error = pa_context_errno(p->context);
190             goto unlock_and_fail;
191         }
192
193         /* Wait until the context is ready */
194         pa_threaded_mainloop_wait(p->mainloop);
195     }
196
197     if (!(p->stream = pa_stream_new(p->context, stream_name, ss, map))) {
198         error = pa_context_errno(p->context);
199         goto unlock_and_fail;
200     }
201
202     pa_stream_set_state_callback(p->stream, stream_state_cb, p);
203     pa_stream_set_read_callback(p->stream, stream_request_cb, p);
204     pa_stream_set_write_callback(p->stream, stream_request_cb, p);
205     pa_stream_set_latency_update_callback(p->stream, stream_latency_update_cb, p);
206
207     if (dir == PA_STREAM_PLAYBACK)
208         r = pa_stream_connect_playback(p->stream, dev, attr,
209                                        PA_STREAM_INTERPOLATE_TIMING
210                                        |PA_STREAM_ADJUST_LATENCY
211                                        |PA_STREAM_AUTO_TIMING_UPDATE, NULL, NULL);
212     else
213         r = pa_stream_connect_record(p->stream, dev, attr,
214                                      PA_STREAM_INTERPOLATE_TIMING
215                                      |PA_STREAM_ADJUST_LATENCY
216                                      |PA_STREAM_AUTO_TIMING_UPDATE);
217
218     if (r < 0) {
219         error = pa_context_errno(p->context);
220         goto unlock_and_fail;
221     }
222
223     for (;;) {
224         pa_stream_state_t state;
225
226         state = pa_stream_get_state(p->stream);
227
228         if (state == PA_STREAM_READY)
229             break;
230
231         if (!PA_STREAM_IS_GOOD(state)) {
232             error = pa_context_errno(p->context);
233             goto unlock_and_fail;
234         }
235
236         /* Wait until the stream is ready */
237         pa_threaded_mainloop_wait(p->mainloop);
238     }
239
240     pa_threaded_mainloop_unlock(p->mainloop);
241
242     return p;
243
244 unlock_and_fail:
245     pa_threaded_mainloop_unlock(p->mainloop);
246
247 fail:
248     if (rerror)
249         *rerror = error;
250     pa_simple_free(p);
251     return NULL;
252 }
253
254 void pa_simple_free(pa_simple *s) {
255     pa_assert(s);
256
257     if (s->mainloop)
258         pa_threaded_mainloop_stop(s->mainloop);
259
260     if (s->stream)
261         pa_stream_unref(s->stream);
262
263     if (s->context) {
264         pa_context_disconnect(s->context);
265         pa_context_unref(s->context);
266     }
267
268     if (s->mainloop)
269         pa_threaded_mainloop_free(s->mainloop);
270
271     pa_xfree(s);
272 }
273
274 int pa_simple_write(pa_simple *p, const void*data, size_t length, int *rerror) {
275     pa_assert(p);
276
277     CHECK_VALIDITY_RETURN_ANY(rerror, p->direction == PA_STREAM_PLAYBACK, PA_ERR_BADSTATE, -1);
278     CHECK_VALIDITY_RETURN_ANY(rerror, data, PA_ERR_INVALID, -1);
279     CHECK_VALIDITY_RETURN_ANY(rerror, length > 0, PA_ERR_INVALID, -1);
280
281     pa_threaded_mainloop_lock(p->mainloop);
282
283     CHECK_DEAD_GOTO(p, rerror, unlock_and_fail);
284
285     while (length > 0) {
286         size_t l;
287         int r;
288
289         while (!(l = pa_stream_writable_size(p->stream))) {
290             pa_threaded_mainloop_wait(p->mainloop);
291             CHECK_DEAD_GOTO(p, rerror, unlock_and_fail);
292         }
293
294         CHECK_SUCCESS_GOTO(p, rerror, l != (size_t) -1, unlock_and_fail);
295
296         if (l > length)
297             l = length;
298
299         r = pa_stream_write(p->stream, data, l, NULL, 0LL, PA_SEEK_RELATIVE);
300         CHECK_SUCCESS_GOTO(p, rerror, r >= 0, unlock_and_fail);
301
302         data = (const uint8_t*) data + l;
303         length -= l;
304     }
305
306     pa_threaded_mainloop_unlock(p->mainloop);
307     return 0;
308
309 unlock_and_fail:
310     pa_threaded_mainloop_unlock(p->mainloop);
311     return -1;
312 }
313
314 int pa_simple_read(pa_simple *p, void*data, size_t length, int *rerror) {
315     pa_assert(p);
316
317     CHECK_VALIDITY_RETURN_ANY(rerror, p->direction == PA_STREAM_RECORD, PA_ERR_BADSTATE, -1);
318     CHECK_VALIDITY_RETURN_ANY(rerror, data, PA_ERR_INVALID, -1);
319     CHECK_VALIDITY_RETURN_ANY(rerror, length > 0, PA_ERR_INVALID, -1);
320
321     pa_threaded_mainloop_lock(p->mainloop);
322
323     CHECK_DEAD_GOTO(p, rerror, unlock_and_fail);
324
325     while (length > 0) {
326         size_t l;
327
328         while (!p->read_data) {
329             int r;
330
331             r = pa_stream_peek(p->stream, &p->read_data, &p->read_length);
332             CHECK_SUCCESS_GOTO(p, rerror, r == 0, unlock_and_fail);
333
334             if (!p->read_data) {
335                 pa_threaded_mainloop_wait(p->mainloop);
336                 CHECK_DEAD_GOTO(p, rerror, unlock_and_fail);
337             } else
338                 p->read_index = 0;
339         }
340
341         l = p->read_length < length ? p->read_length : length;
342         memcpy(data, (const uint8_t*) p->read_data+p->read_index, l);
343
344         data = (uint8_t*) data + l;
345         length -= l;
346
347         p->read_index += l;
348         p->read_length -= l;
349
350         if (!p->read_length) {
351             int r;
352
353             r = pa_stream_drop(p->stream);
354             p->read_data = NULL;
355             p->read_length = 0;
356             p->read_index = 0;
357
358             CHECK_SUCCESS_GOTO(p, rerror, r == 0, unlock_and_fail);
359         }
360     }
361
362     pa_threaded_mainloop_unlock(p->mainloop);
363     return 0;
364
365 unlock_and_fail:
366     pa_threaded_mainloop_unlock(p->mainloop);
367     return -1;
368 }
369
370 static void success_cb(pa_stream *s, int success, void *userdata) {
371     pa_simple *p = userdata;
372
373     pa_assert(s);
374     pa_assert(p);
375
376     p->operation_success = success;
377     pa_threaded_mainloop_signal(p->mainloop, 0);
378 }
379
380 int pa_simple_drain(pa_simple *p, int *rerror) {
381     pa_operation *o = NULL;
382
383     pa_assert(p);
384
385     CHECK_VALIDITY_RETURN_ANY(rerror, p->direction == PA_STREAM_PLAYBACK, PA_ERR_BADSTATE, -1);
386
387     pa_threaded_mainloop_lock(p->mainloop);
388     CHECK_DEAD_GOTO(p, rerror, unlock_and_fail);
389
390     o = pa_stream_drain(p->stream, success_cb, p);
391     CHECK_SUCCESS_GOTO(p, rerror, o, unlock_and_fail);
392
393     p->operation_success = 0;
394     while (pa_operation_get_state(o) == PA_OPERATION_RUNNING) {
395         pa_threaded_mainloop_wait(p->mainloop);
396         CHECK_DEAD_GOTO(p, rerror, unlock_and_fail);
397     }
398     CHECK_SUCCESS_GOTO(p, rerror, p->operation_success, unlock_and_fail);
399
400     pa_operation_unref(o);
401     pa_threaded_mainloop_unlock(p->mainloop);
402
403     return 0;
404
405 unlock_and_fail:
406
407     if (o) {
408         pa_operation_cancel(o);
409         pa_operation_unref(o);
410     }
411
412     pa_threaded_mainloop_unlock(p->mainloop);
413     return -1;
414 }
415
416 int pa_simple_flush(pa_simple *p, int *rerror) {
417     pa_operation *o = NULL;
418
419     pa_assert(p);
420
421     CHECK_VALIDITY_RETURN_ANY(rerror, p->direction == PA_STREAM_PLAYBACK, PA_ERR_BADSTATE, -1);
422
423     pa_threaded_mainloop_lock(p->mainloop);
424     CHECK_DEAD_GOTO(p, rerror, unlock_and_fail);
425
426     o = pa_stream_flush(p->stream, success_cb, p);
427     CHECK_SUCCESS_GOTO(p, rerror, o, unlock_and_fail);
428
429     p->operation_success = 0;
430     while (pa_operation_get_state(o) == PA_OPERATION_RUNNING) {
431         pa_threaded_mainloop_wait(p->mainloop);
432         CHECK_DEAD_GOTO(p, rerror, unlock_and_fail);
433     }
434     CHECK_SUCCESS_GOTO(p, rerror, p->operation_success, unlock_and_fail);
435
436     pa_operation_unref(o);
437     pa_threaded_mainloop_unlock(p->mainloop);
438
439     return 0;
440
441 unlock_and_fail:
442
443     if (o) {
444         pa_operation_cancel(o);
445         pa_operation_unref(o);
446     }
447
448     pa_threaded_mainloop_unlock(p->mainloop);
449     return -1;
450 }
451
452 pa_usec_t pa_simple_get_latency(pa_simple *p, int *rerror) {
453     pa_usec_t t;
454     int negative;
455
456     pa_assert(p);
457
458     pa_threaded_mainloop_lock(p->mainloop);
459
460     for (;;) {
461         CHECK_DEAD_GOTO(p, rerror, unlock_and_fail);
462
463         if (pa_stream_get_latency(p->stream, &t, &negative) >= 0)
464             break;
465
466         CHECK_SUCCESS_GOTO(p, rerror, pa_context_errno(p->context) == PA_ERR_NODATA, unlock_and_fail);
467
468         /* Wait until latency data is available again */
469         pa_threaded_mainloop_wait(p->mainloop);
470     }
471
472     pa_threaded_mainloop_unlock(p->mainloop);
473
474     return negative ? 0 : t;
475
476 unlock_and_fail:
477
478     pa_threaded_mainloop_unlock(p->mainloop);
479     return (pa_usec_t) -1;
480 }