Fix indent
[platform/upstream/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/native-common.h>
36 #include <pulsecore/log.h>
37 #include <pulsecore/macro.h>
38
39 #include "simple.h"
40 #include "internal.h"
41
42 struct pa_simple {
43     pa_threaded_mainloop *mainloop;
44     pa_context *context;
45     pa_stream *stream;
46     pa_stream_direction_t direction;
47
48     const void *read_data;
49     size_t read_index, read_length;
50
51     int operation_success;
52 };
53
54 #define CHECK_VALIDITY_RETURN_ANY(rerror, expression, error, ret)       \
55     do {                                                                \
56         if (!(expression)) {                                            \
57             if (rerror)                                                 \
58                 *(rerror) = error;                                      \
59             return (ret);                                               \
60         }                                                               \
61     } while(false);
62
63 #define CHECK_SUCCESS_GOTO(p, rerror, expression, label)        \
64     do {                                                        \
65         if (!(expression)) {                                    \
66             if (rerror)                                         \
67                 *(rerror) = pa_context_errno((p)->context);     \
68             goto label;                                         \
69         }                                                       \
70     } while(false);
71
72 #define CHECK_DEAD_GOTO(p, rerror, label)                               \
73     do {                                                                \
74         if (!(p)->context || !PA_CONTEXT_IS_GOOD(pa_context_get_state((p)->context)) || \
75             !(p)->stream || !PA_STREAM_IS_GOOD(pa_stream_get_state((p)->stream))) { \
76             if (((p)->context && pa_context_get_state((p)->context) == PA_CONTEXT_FAILED) || \
77                 ((p)->stream && pa_stream_get_state((p)->stream) == PA_STREAM_FAILED)) { \
78                 if (rerror)                                             \
79                     *(rerror) = pa_context_errno((p)->context);         \
80             } else                                                      \
81                 if (rerror)                                             \
82                     *(rerror) = PA_ERR_BADSTATE;                        \
83             goto label;                                                 \
84         }                                                               \
85     } while(false);
86
87 static void context_state_cb(pa_context *c, void *userdata) {
88     pa_simple *p = userdata;
89     pa_assert(c);
90     pa_assert(p);
91
92     switch (pa_context_get_state(c)) {
93         case PA_CONTEXT_READY:
94         case PA_CONTEXT_TERMINATED:
95         case PA_CONTEXT_FAILED:
96             pa_threaded_mainloop_signal(p->mainloop, 0);
97             break;
98
99         case PA_CONTEXT_UNCONNECTED:
100         case PA_CONTEXT_CONNECTING:
101         case PA_CONTEXT_AUTHORIZING:
102         case PA_CONTEXT_SETTING_NAME:
103             break;
104     }
105 }
106
107 static void stream_success_context_cb(pa_stream *s, int success, void *userdata) {
108     pa_simple *p = userdata;
109     pa_assert(s);
110     pa_assert(p);
111
112     p->operation_success = success;
113     pa_threaded_mainloop_signal(p->mainloop, 0);
114 }
115
116 static void success_context_cb(pa_context *c, int success, void *userdata) {
117     pa_simple *p = userdata;
118     pa_assert(c);
119     pa_assert(p);
120
121     p->operation_success = success;
122     pa_threaded_mainloop_signal(p->mainloop, 0);
123 }
124
125 static void stream_state_cb(pa_stream *s, void * userdata) {
126     pa_simple *p = userdata;
127     pa_assert(s);
128     pa_assert(p);
129
130     switch (pa_stream_get_state(s)) {
131
132         case PA_STREAM_READY:
133         case PA_STREAM_FAILED:
134         case PA_STREAM_TERMINATED:
135             pa_threaded_mainloop_signal(p->mainloop, 0);
136             break;
137
138         case PA_STREAM_UNCONNECTED:
139         case PA_STREAM_CREATING:
140             break;
141     }
142 }
143
144 static void stream_request_cb(pa_stream *s, size_t length, void *userdata) {
145     pa_simple *p = userdata;
146     pa_assert(p);
147
148     pa_threaded_mainloop_signal(p->mainloop, 0);
149 }
150
151 static void stream_latency_update_cb(pa_stream *s, void *userdata) {
152     pa_simple *p = userdata;
153
154     pa_assert(p);
155
156     pa_threaded_mainloop_signal(p->mainloop, 0);
157 }
158
159 pa_simple* pa_simple_new(
160         const char *server,
161         const char *name,
162         pa_stream_direction_t dir,
163         const char *dev,
164         const char *stream_name,
165         const pa_sample_spec *ss,
166         const pa_channel_map *map,
167         const pa_buffer_attr *attr,
168         int *rerror) {
169
170     pa_simple *p;
171     int error = PA_ERR_INTERNAL, r;
172
173     CHECK_VALIDITY_RETURN_ANY(rerror, !server || *server, PA_ERR_INVALID, NULL);
174     CHECK_VALIDITY_RETURN_ANY(rerror, dir == PA_STREAM_PLAYBACK || dir == PA_STREAM_RECORD, PA_ERR_INVALID, NULL);
175     CHECK_VALIDITY_RETURN_ANY(rerror, !dev || *dev, PA_ERR_INVALID, NULL);
176     CHECK_VALIDITY_RETURN_ANY(rerror, ss && pa_sample_spec_valid(ss), PA_ERR_INVALID, NULL);
177     CHECK_VALIDITY_RETURN_ANY(rerror, !map || (pa_channel_map_valid(map) && map->channels == ss->channels), PA_ERR_INVALID, NULL)
178
179     p = pa_xnew0(pa_simple, 1);
180     p->direction = dir;
181
182     if (!(p->mainloop = pa_threaded_mainloop_new()))
183         goto fail;
184
185     if (!(p->context = pa_context_new(pa_threaded_mainloop_get_api(p->mainloop), name)))
186         goto fail;
187
188     pa_context_set_state_callback(p->context, context_state_cb, p);
189
190     if (pa_context_connect(p->context, server, 0, NULL) < 0) {
191         error = pa_context_errno(p->context);
192         goto fail;
193     }
194
195     pa_threaded_mainloop_lock(p->mainloop);
196
197     if (pa_threaded_mainloop_start(p->mainloop) < 0)
198         goto unlock_and_fail;
199
200     for (;;) {
201         pa_context_state_t state;
202
203         state = pa_context_get_state(p->context);
204
205         if (state == PA_CONTEXT_READY)
206             break;
207
208         if (!PA_CONTEXT_IS_GOOD(state)) {
209             error = pa_context_errno(p->context);
210             goto unlock_and_fail;
211         }
212
213         /* Wait until the context is ready */
214         pa_threaded_mainloop_wait(p->mainloop);
215     }
216
217     if (!(p->stream = pa_stream_new(p->context, stream_name, ss, map))) {
218         error = pa_context_errno(p->context);
219         goto unlock_and_fail;
220     }
221
222     pa_stream_set_state_callback(p->stream, stream_state_cb, p);
223     pa_stream_set_read_callback(p->stream, stream_request_cb, p);
224     pa_stream_set_write_callback(p->stream, stream_request_cb, p);
225     pa_stream_set_latency_update_callback(p->stream, stream_latency_update_cb, p);
226
227     if (dir == PA_STREAM_PLAYBACK)
228         r = pa_stream_connect_playback(p->stream, dev, attr,
229                                        PA_STREAM_INTERPOLATE_TIMING
230                                        |PA_STREAM_ADJUST_LATENCY
231                                        |PA_STREAM_AUTO_TIMING_UPDATE, NULL, NULL);
232     else
233         r = pa_stream_connect_record(p->stream, dev, attr,
234                                      PA_STREAM_INTERPOLATE_TIMING
235                                      |PA_STREAM_ADJUST_LATENCY
236                                      |PA_STREAM_AUTO_TIMING_UPDATE);
237
238     if (r < 0) {
239         error = pa_context_errno(p->context);
240         goto unlock_and_fail;
241     }
242
243     for (;;) {
244         pa_stream_state_t state;
245
246         state = pa_stream_get_state(p->stream);
247
248         if (state == PA_STREAM_READY)
249             break;
250
251         if (!PA_STREAM_IS_GOOD(state)) {
252             error = pa_context_errno(p->context);
253             goto unlock_and_fail;
254         }
255
256         /* Wait until the stream is ready */
257         pa_threaded_mainloop_wait(p->mainloop);
258     }
259
260     pa_threaded_mainloop_unlock(p->mainloop);
261
262     return p;
263
264 unlock_and_fail:
265     pa_threaded_mainloop_unlock(p->mainloop);
266
267 fail:
268     if (rerror)
269         *rerror = error;
270     pa_simple_free(p);
271     return NULL;
272 }
273
274 pa_simple* pa_simple_new_proplist(
275         const char *server,
276         const char *name,
277         pa_stream_direction_t dir,
278         const char *dev,
279         const char *stream_name,
280         const pa_sample_spec *ss,
281         const pa_channel_map *map,
282         const pa_buffer_attr *attr,
283         pa_proplist *proplist,
284         int *rerror) {
285
286     pa_simple *p;
287     int error = PA_ERR_INTERNAL, r;
288
289     CHECK_VALIDITY_RETURN_ANY(rerror, !server || *server, PA_ERR_INVALID, NULL);
290     CHECK_VALIDITY_RETURN_ANY(rerror, dir == PA_STREAM_PLAYBACK || dir == PA_STREAM_RECORD, PA_ERR_INVALID, NULL);
291     CHECK_VALIDITY_RETURN_ANY(rerror, !dev || *dev, PA_ERR_INVALID, NULL);
292     CHECK_VALIDITY_RETURN_ANY(rerror, ss && pa_sample_spec_valid(ss), PA_ERR_INVALID, NULL);
293     CHECK_VALIDITY_RETURN_ANY(rerror, !map || (pa_channel_map_valid(map) && map->channels == ss->channels), PA_ERR_INVALID, NULL)
294
295     p = pa_xnew0(pa_simple, 1);
296     p->direction = dir;
297
298     if (!(p->mainloop = pa_threaded_mainloop_new()))
299         goto fail;
300
301     if (!(p->context = pa_context_new(pa_threaded_mainloop_get_api(p->mainloop), name)))
302         goto fail;
303
304     pa_context_set_state_callback(p->context, context_state_cb, p);
305
306     if (pa_context_connect(p->context, server, 0, NULL) < 0) {
307         error = pa_context_errno(p->context);
308         goto fail;
309     }
310
311     pa_threaded_mainloop_lock(p->mainloop);
312
313     if (pa_threaded_mainloop_start(p->mainloop) < 0)
314         goto unlock_and_fail;
315
316     for (;;) {
317         pa_context_state_t state;
318
319         state = pa_context_get_state(p->context);
320
321         if (state == PA_CONTEXT_READY)
322             break;
323
324         if (!PA_CONTEXT_IS_GOOD(state)) {
325             error = pa_context_errno(p->context);
326             goto unlock_and_fail;
327         }
328
329         /* Wait until the context is ready */
330         pa_threaded_mainloop_wait(p->mainloop);
331     }
332
333     if (!(p->stream = pa_stream_new_with_proplist(p->context, stream_name, ss, map, proplist))) {
334         error = pa_context_errno(p->context);
335         goto unlock_and_fail;
336     }
337
338     pa_stream_set_state_callback(p->stream, stream_state_cb, p);
339     pa_stream_set_read_callback(p->stream, stream_request_cb, p);
340     pa_stream_set_write_callback(p->stream, stream_request_cb, p);
341     pa_stream_set_latency_update_callback(p->stream, stream_latency_update_cb, p);
342
343     if (dir == PA_STREAM_PLAYBACK)
344         r = pa_stream_connect_playback(p->stream, dev, attr,
345                                        PA_STREAM_INTERPOLATE_TIMING
346                                        |PA_STREAM_ADJUST_LATENCY
347                                        |PA_STREAM_AUTO_TIMING_UPDATE, NULL, NULL);
348     else
349         r = pa_stream_connect_record(p->stream, dev, attr,
350                                      PA_STREAM_INTERPOLATE_TIMING
351                                      |PA_STREAM_ADJUST_LATENCY
352                                      |PA_STREAM_AUTO_TIMING_UPDATE
353                                      |PA_STREAM_START_CORKED);
354
355     if (r < 0) {
356         error = pa_context_errno(p->context);
357         goto unlock_and_fail;
358     }
359
360     for (;;) {
361         pa_stream_state_t state;
362
363         state = pa_stream_get_state(p->stream);
364
365         if (state == PA_STREAM_READY)
366             break;
367
368         if (!PA_STREAM_IS_GOOD(state)) {
369             error = pa_context_errno(p->context);
370             goto unlock_and_fail;
371         }
372
373         /* Wait until the stream is ready */
374         pa_threaded_mainloop_wait(p->mainloop);
375     }
376
377     pa_threaded_mainloop_unlock(p->mainloop);
378
379     return p;
380
381 unlock_and_fail:
382     pa_threaded_mainloop_unlock(p->mainloop);
383
384 fail:
385     if (rerror)
386         *rerror = error;
387     pa_simple_free(p);
388     return NULL;
389 }
390 void pa_simple_free(pa_simple *s) {
391     pa_assert(s);
392
393     if (s->mainloop)
394         pa_threaded_mainloop_stop(s->mainloop);
395
396     if (s->stream)
397         pa_stream_unref(s->stream);
398
399     if (s->context) {
400         pa_context_disconnect(s->context);
401         pa_context_unref(s->context);
402     }
403
404     if (s->mainloop)
405         pa_threaded_mainloop_free(s->mainloop);
406
407     pa_xfree(s);
408 }
409
410 int pa_simple_write(pa_simple *p, const void*data, size_t length, int *rerror) {
411     pa_assert(p);
412
413     CHECK_VALIDITY_RETURN_ANY(rerror, p->direction == PA_STREAM_PLAYBACK, PA_ERR_BADSTATE, -1);
414     CHECK_VALIDITY_RETURN_ANY(rerror, data, PA_ERR_INVALID, -1);
415     CHECK_VALIDITY_RETURN_ANY(rerror, length > 0, PA_ERR_INVALID, -1);
416
417     pa_threaded_mainloop_lock(p->mainloop);
418
419     CHECK_DEAD_GOTO(p, rerror, unlock_and_fail);
420
421     while (length > 0) {
422         size_t l;
423         int r;
424
425         while (!(l = pa_stream_writable_size(p->stream))) {
426             pa_threaded_mainloop_wait(p->mainloop);
427             CHECK_DEAD_GOTO(p, rerror, unlock_and_fail);
428         }
429
430         CHECK_SUCCESS_GOTO(p, rerror, l != (size_t) -1, unlock_and_fail);
431
432         if (l > length)
433             l = length;
434
435         r = pa_stream_write(p->stream, data, l, NULL, 0LL, PA_SEEK_RELATIVE);
436         CHECK_SUCCESS_GOTO(p, rerror, r >= 0, unlock_and_fail);
437
438         data = (const uint8_t*) data + l;
439         length -= l;
440     }
441
442     pa_threaded_mainloop_unlock(p->mainloop);
443     return 0;
444
445 unlock_and_fail:
446     pa_threaded_mainloop_unlock(p->mainloop);
447     return -1;
448 }
449
450 int pa_simple_read(pa_simple *p, void*data, size_t length, int *rerror) {
451     pa_assert(p);
452
453     CHECK_VALIDITY_RETURN_ANY(rerror, p->direction == PA_STREAM_RECORD, PA_ERR_BADSTATE, -1);
454     CHECK_VALIDITY_RETURN_ANY(rerror, data, PA_ERR_INVALID, -1);
455     CHECK_VALIDITY_RETURN_ANY(rerror, length > 0, PA_ERR_INVALID, -1);
456
457     pa_threaded_mainloop_lock(p->mainloop);
458
459     CHECK_DEAD_GOTO(p, rerror, unlock_and_fail);
460
461     while (length > 0) {
462         size_t l;
463
464         while (!p->read_data) {
465             int r;
466
467             r = pa_stream_peek(p->stream, &p->read_data, &p->read_length);
468             CHECK_SUCCESS_GOTO(p, rerror, r == 0, unlock_and_fail);
469
470             if (p->read_length <= 0) {
471                 pa_threaded_mainloop_wait(p->mainloop);
472                 CHECK_DEAD_GOTO(p, rerror, unlock_and_fail);
473             } else if (!p->read_data) {
474                 /* There's a hole in the stream, skip it. We could generate
475                  * silence, but that wouldn't work for compressed streams. */
476                 r = pa_stream_drop(p->stream);
477                 CHECK_SUCCESS_GOTO(p, rerror, r == 0, unlock_and_fail);
478             } else
479                 p->read_index = 0;
480         }
481
482         l = p->read_length < length ? p->read_length : length;
483         memcpy(data, (const uint8_t*) p->read_data+p->read_index, l);
484
485         data = (uint8_t*) data + l;
486         length -= l;
487
488         p->read_index += l;
489         p->read_length -= l;
490
491         if (!p->read_length) {
492             int r;
493
494             r = pa_stream_drop(p->stream);
495             p->read_data = NULL;
496             p->read_length = 0;
497             p->read_index = 0;
498
499             CHECK_SUCCESS_GOTO(p, rerror, r == 0, unlock_and_fail);
500         }
501     }
502
503     pa_threaded_mainloop_unlock(p->mainloop);
504     return 0;
505
506 unlock_and_fail:
507     pa_threaded_mainloop_unlock(p->mainloop);
508     return -1;
509 }
510
511 static void success_cb(pa_stream *s, int success, void *userdata) {
512     pa_simple *p = userdata;
513
514     pa_assert(s);
515     pa_assert(p);
516
517     p->operation_success = success;
518     pa_threaded_mainloop_signal(p->mainloop, 0);
519 }
520
521 int pa_simple_drain(pa_simple *p, int *rerror) {
522     pa_operation *o = NULL;
523
524     pa_assert(p);
525
526     CHECK_VALIDITY_RETURN_ANY(rerror, p->direction == PA_STREAM_PLAYBACK, PA_ERR_BADSTATE, -1);
527
528     pa_threaded_mainloop_lock(p->mainloop);
529     CHECK_DEAD_GOTO(p, rerror, unlock_and_fail);
530
531     o = pa_stream_drain(p->stream, success_cb, p);
532     CHECK_SUCCESS_GOTO(p, rerror, o, unlock_and_fail);
533
534     p->operation_success = 0;
535     while (pa_operation_get_state(o) == PA_OPERATION_RUNNING) {
536         pa_threaded_mainloop_wait(p->mainloop);
537         CHECK_DEAD_GOTO(p, rerror, unlock_and_fail);
538     }
539     CHECK_SUCCESS_GOTO(p, rerror, p->operation_success, unlock_and_fail);
540
541     pa_operation_unref(o);
542     pa_threaded_mainloop_unlock(p->mainloop);
543
544     return 0;
545
546 unlock_and_fail:
547
548     if (o) {
549         pa_operation_cancel(o);
550         pa_operation_unref(o);
551     }
552
553     pa_threaded_mainloop_unlock(p->mainloop);
554     return -1;
555 }
556
557 int pa_simple_flush(pa_simple *p, int *rerror) {
558     pa_operation *o = NULL;
559
560     pa_assert(p);
561
562     pa_threaded_mainloop_lock(p->mainloop);
563     CHECK_DEAD_GOTO(p, rerror, unlock_and_fail);
564
565     o = pa_stream_flush(p->stream, success_cb, p);
566     CHECK_SUCCESS_GOTO(p, rerror, o, unlock_and_fail);
567
568     p->operation_success = 0;
569     while (pa_operation_get_state(o) == PA_OPERATION_RUNNING) {
570         pa_threaded_mainloop_wait(p->mainloop);
571         CHECK_DEAD_GOTO(p, rerror, unlock_and_fail);
572     }
573     CHECK_SUCCESS_GOTO(p, rerror, p->operation_success, unlock_and_fail);
574
575     pa_operation_unref(o);
576     pa_threaded_mainloop_unlock(p->mainloop);
577
578     return 0;
579
580 unlock_and_fail:
581
582     if (o) {
583         pa_operation_cancel(o);
584         pa_operation_unref(o);
585     }
586
587     pa_threaded_mainloop_unlock(p->mainloop);
588     return -1;
589 }
590
591 int pa_simple_get_stream_index(pa_simple *p, unsigned int *idx, int *rerror) {
592     pa_assert(p);
593     CHECK_VALIDITY_RETURN_ANY(rerror, idx != NULL, PA_ERR_INVALID, -1);
594
595     pa_threaded_mainloop_lock(p->mainloop);
596
597     CHECK_DEAD_GOTO(p, rerror, unlock_and_fail);
598
599     *idx = pa_stream_get_index(p->stream);
600
601     pa_threaded_mainloop_unlock(p->mainloop);
602     return 0;
603
604 unlock_and_fail:
605     pa_threaded_mainloop_unlock(p->mainloop);
606     return -1;
607 }
608
609 pa_usec_t pa_simple_get_latency(pa_simple *p, int *rerror) {
610     pa_usec_t t;
611     int negative;
612
613     pa_assert(p);
614
615     pa_threaded_mainloop_lock(p->mainloop);
616
617     for (;;) {
618         CHECK_DEAD_GOTO(p, rerror, unlock_and_fail);
619
620         if (pa_stream_get_latency(p->stream, &t, &negative) >= 0)
621             break;
622
623         CHECK_SUCCESS_GOTO(p, rerror, pa_context_errno(p->context) == PA_ERR_NODATA, unlock_and_fail);
624
625         /* Wait until latency data is available again */
626         pa_threaded_mainloop_wait(p->mainloop);
627     }
628
629     pa_threaded_mainloop_unlock(p->mainloop);
630
631     return negative ? 0 : t;
632
633 unlock_and_fail:
634
635     pa_threaded_mainloop_unlock(p->mainloop);
636     return (pa_usec_t) -1;
637 }