3 This file is part of PulseAudio.
5 Copyright 2004-2006 Lennart Poettering
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.
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.
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
31 #include <pulse/pulseaudio.h>
32 #include <pulse/thread-mainloop.h>
33 #include <pulse/xmalloc.h>
35 #include <pulsecore/log.h>
36 #include <pulsecore/macro.h>
43 pa_threaded_mainloop *mainloop;
46 pa_stream_direction_t direction;
48 const void *read_data;
49 size_t read_index, read_length;
51 int operation_success;
54 #define CHECK_VALIDITY_RETURN_ANY(rerror, expression, error, ret) \
56 if (!(expression)) { \
63 #define CHECK_SUCCESS_GOTO(p, rerror, expression, label) \
65 if (!(expression)) { \
67 *(rerror) = pa_context_errno((p)->context); \
72 #define CHECK_DEAD_GOTO(p, rerror, label) \
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)) { \
79 *(rerror) = pa_context_errno((p)->context); \
82 *(rerror) = PA_ERR_BADSTATE; \
87 static void context_state_cb(pa_context *c, void *userdata) {
88 pa_simple *p = userdata;
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);
99 case PA_CONTEXT_UNCONNECTED:
100 case PA_CONTEXT_CONNECTING:
101 case PA_CONTEXT_AUTHORIZING:
102 case PA_CONTEXT_SETTING_NAME:
107 static void success_context_cb(pa_context *c, int success, void *userdata) {
108 pa_simple *p = userdata;
112 p->operation_success = success;
113 pa_threaded_mainloop_signal(p->mainloop, 0);
116 static void stream_state_cb(pa_stream *s, void * userdata) {
117 pa_simple *p = userdata;
121 switch (pa_stream_get_state(s)) {
123 case PA_STREAM_READY:
124 case PA_STREAM_FAILED:
125 case PA_STREAM_TERMINATED:
126 pa_threaded_mainloop_signal(p->mainloop, 0);
129 case PA_STREAM_UNCONNECTED:
130 case PA_STREAM_CREATING:
135 static void stream_request_cb(pa_stream *s, size_t length, void *userdata) {
136 pa_simple *p = userdata;
139 pa_threaded_mainloop_signal(p->mainloop, 0);
142 static void stream_latency_update_cb(pa_stream *s, void *userdata) {
143 pa_simple *p = userdata;
147 pa_threaded_mainloop_signal(p->mainloop, 0);
150 pa_simple* pa_simple_new(
153 pa_stream_direction_t dir,
155 const char *stream_name,
156 const pa_sample_spec *ss,
157 const pa_channel_map *map,
158 const pa_buffer_attr *attr,
162 int error = PA_ERR_INTERNAL, r;
164 CHECK_VALIDITY_RETURN_ANY(rerror, !server || *server, PA_ERR_INVALID, NULL);
165 CHECK_VALIDITY_RETURN_ANY(rerror, dir == PA_STREAM_PLAYBACK || dir == PA_STREAM_RECORD, PA_ERR_INVALID, NULL);
166 CHECK_VALIDITY_RETURN_ANY(rerror, !dev || *dev, PA_ERR_INVALID, NULL);
167 CHECK_VALIDITY_RETURN_ANY(rerror, ss && pa_sample_spec_valid(ss), PA_ERR_INVALID, NULL);
168 CHECK_VALIDITY_RETURN_ANY(rerror, !map || (pa_channel_map_valid(map) && map->channels == ss->channels), PA_ERR_INVALID, NULL)
170 p = pa_xnew0(pa_simple, 1);
173 if (!(p->mainloop = pa_threaded_mainloop_new()))
176 if (!(p->context = pa_context_new(pa_threaded_mainloop_get_api(p->mainloop), name)))
179 pa_context_set_state_callback(p->context, context_state_cb, p);
181 if (pa_context_connect(p->context, server, 0, NULL) < 0) {
182 error = pa_context_errno(p->context);
186 pa_threaded_mainloop_lock(p->mainloop);
188 if (pa_threaded_mainloop_start(p->mainloop) < 0)
189 goto unlock_and_fail;
192 pa_context_state_t state;
194 state = pa_context_get_state(p->context);
196 if (state == PA_CONTEXT_READY)
199 if (!PA_CONTEXT_IS_GOOD(state)) {
200 error = pa_context_errno(p->context);
201 goto unlock_and_fail;
204 /* Wait until the context is ready */
205 pa_threaded_mainloop_wait(p->mainloop);
208 if (!(p->stream = pa_stream_new(p->context, stream_name, ss, map))) {
209 error = pa_context_errno(p->context);
210 goto unlock_and_fail;
213 pa_stream_set_state_callback(p->stream, stream_state_cb, p);
214 pa_stream_set_read_callback(p->stream, stream_request_cb, p);
215 pa_stream_set_write_callback(p->stream, stream_request_cb, p);
216 pa_stream_set_latency_update_callback(p->stream, stream_latency_update_cb, p);
218 if (dir == PA_STREAM_PLAYBACK)
219 r = pa_stream_connect_playback(p->stream, dev, attr,
220 PA_STREAM_INTERPOLATE_TIMING
221 |PA_STREAM_ADJUST_LATENCY
222 |PA_STREAM_AUTO_TIMING_UPDATE, NULL, NULL);
224 r = pa_stream_connect_record(p->stream, dev, attr,
225 PA_STREAM_INTERPOLATE_TIMING
226 |PA_STREAM_ADJUST_LATENCY
227 |PA_STREAM_AUTO_TIMING_UPDATE);
230 error = pa_context_errno(p->context);
231 goto unlock_and_fail;
235 pa_stream_state_t state;
237 state = pa_stream_get_state(p->stream);
239 if (state == PA_STREAM_READY)
242 if (!PA_STREAM_IS_GOOD(state)) {
243 error = pa_context_errno(p->context);
244 goto unlock_and_fail;
247 /* Wait until the stream is ready */
248 pa_threaded_mainloop_wait(p->mainloop);
251 pa_threaded_mainloop_unlock(p->mainloop);
256 pa_threaded_mainloop_unlock(p->mainloop);
265 void pa_simple_free(pa_simple *s) {
269 pa_threaded_mainloop_stop(s->mainloop);
272 pa_stream_unref(s->stream);
275 pa_context_disconnect(s->context);
276 pa_context_unref(s->context);
280 pa_threaded_mainloop_free(s->mainloop);
285 int pa_simple_write(pa_simple *p, const void*data, size_t length, int *rerror) {
288 CHECK_VALIDITY_RETURN_ANY(rerror, p->direction == PA_STREAM_PLAYBACK, PA_ERR_BADSTATE, -1);
289 CHECK_VALIDITY_RETURN_ANY(rerror, data, PA_ERR_INVALID, -1);
290 CHECK_VALIDITY_RETURN_ANY(rerror, length > 0, PA_ERR_INVALID, -1);
292 pa_threaded_mainloop_lock(p->mainloop);
294 CHECK_DEAD_GOTO(p, rerror, unlock_and_fail);
300 while (!(l = pa_stream_writable_size(p->stream))) {
301 pa_threaded_mainloop_wait(p->mainloop);
302 CHECK_DEAD_GOTO(p, rerror, unlock_and_fail);
305 CHECK_SUCCESS_GOTO(p, rerror, l != (size_t) -1, unlock_and_fail);
310 r = pa_stream_write(p->stream, data, l, NULL, 0LL, PA_SEEK_RELATIVE);
311 CHECK_SUCCESS_GOTO(p, rerror, r >= 0, unlock_and_fail);
313 data = (const uint8_t*) data + l;
317 pa_threaded_mainloop_unlock(p->mainloop);
321 pa_threaded_mainloop_unlock(p->mainloop);
325 int pa_simple_read(pa_simple *p, void*data, size_t length, int *rerror) {
328 CHECK_VALIDITY_RETURN_ANY(rerror, p->direction == PA_STREAM_RECORD, PA_ERR_BADSTATE, -1);
329 CHECK_VALIDITY_RETURN_ANY(rerror, data, PA_ERR_INVALID, -1);
330 CHECK_VALIDITY_RETURN_ANY(rerror, length > 0, PA_ERR_INVALID, -1);
332 pa_threaded_mainloop_lock(p->mainloop);
334 CHECK_DEAD_GOTO(p, rerror, unlock_and_fail);
339 while (!p->read_data) {
342 r = pa_stream_peek(p->stream, &p->read_data, &p->read_length);
343 CHECK_SUCCESS_GOTO(p, rerror, r == 0, unlock_and_fail);
346 pa_threaded_mainloop_wait(p->mainloop);
347 CHECK_DEAD_GOTO(p, rerror, unlock_and_fail);
352 l = p->read_length < length ? p->read_length : length;
353 memcpy(data, (const uint8_t*) p->read_data+p->read_index, l);
355 data = (uint8_t*) data + l;
361 if (!p->read_length) {
364 r = pa_stream_drop(p->stream);
369 CHECK_SUCCESS_GOTO(p, rerror, r == 0, unlock_and_fail);
373 pa_threaded_mainloop_unlock(p->mainloop);
377 pa_threaded_mainloop_unlock(p->mainloop);
381 static void success_cb(pa_stream *s, int success, void *userdata) {
382 pa_simple *p = userdata;
387 p->operation_success = success;
388 pa_threaded_mainloop_signal(p->mainloop, 0);
391 int pa_simple_drain(pa_simple *p, int *rerror) {
392 pa_operation *o = NULL;
396 CHECK_VALIDITY_RETURN_ANY(rerror, p->direction == PA_STREAM_PLAYBACK, PA_ERR_BADSTATE, -1);
398 pa_threaded_mainloop_lock(p->mainloop);
399 CHECK_DEAD_GOTO(p, rerror, unlock_and_fail);
401 o = pa_stream_drain(p->stream, success_cb, p);
402 CHECK_SUCCESS_GOTO(p, rerror, o, unlock_and_fail);
404 p->operation_success = 0;
405 while (pa_operation_get_state(o) == PA_OPERATION_RUNNING) {
406 pa_threaded_mainloop_wait(p->mainloop);
407 CHECK_DEAD_GOTO(p, rerror, unlock_and_fail);
409 CHECK_SUCCESS_GOTO(p, rerror, p->operation_success, unlock_and_fail);
411 pa_operation_unref(o);
412 pa_threaded_mainloop_unlock(p->mainloop);
419 pa_operation_cancel(o);
420 pa_operation_unref(o);
423 pa_threaded_mainloop_unlock(p->mainloop);
427 int pa_simple_flush(pa_simple *p, int *rerror) {
428 pa_operation *o = NULL;
432 CHECK_VALIDITY_RETURN_ANY(rerror, p->direction == PA_STREAM_PLAYBACK, PA_ERR_BADSTATE, -1);
434 pa_threaded_mainloop_lock(p->mainloop);
435 CHECK_DEAD_GOTO(p, rerror, unlock_and_fail);
437 o = pa_stream_flush(p->stream, success_cb, p);
438 CHECK_SUCCESS_GOTO(p, rerror, o, unlock_and_fail);
440 p->operation_success = 0;
441 while (pa_operation_get_state(o) == PA_OPERATION_RUNNING) {
442 pa_threaded_mainloop_wait(p->mainloop);
443 CHECK_DEAD_GOTO(p, rerror, unlock_and_fail);
445 CHECK_SUCCESS_GOTO(p, rerror, p->operation_success, unlock_and_fail);
447 pa_operation_unref(o);
448 pa_threaded_mainloop_unlock(p->mainloop);
455 pa_operation_cancel(o);
456 pa_operation_unref(o);
459 pa_threaded_mainloop_unlock(p->mainloop);
463 pa_usec_t pa_simple_get_latency(pa_simple *p, int *rerror) {
469 pa_threaded_mainloop_lock(p->mainloop);
472 CHECK_DEAD_GOTO(p, rerror, unlock_and_fail);
474 if (pa_stream_get_latency(p->stream, &t, &negative) >= 0)
477 CHECK_SUCCESS_GOTO(p, rerror, pa_context_errno(p->context) == PA_ERR_NODATA, unlock_and_fail);
479 /* Wait until latency data is available again */
480 pa_threaded_mainloop_wait(p->mainloop);
483 pa_threaded_mainloop_unlock(p->mainloop);
485 return negative ? 0 : t;
489 pa_threaded_mainloop_unlock(p->mainloop);
490 return (pa_usec_t) -1;
493 pa_simple* pa_simple_new_proplist(
496 pa_stream_direction_t dir,
498 const char *stream_name,
499 const pa_sample_spec *ss,
500 const pa_channel_map *map,
501 const pa_buffer_attr *attr,
502 pa_proplist *proplist,
506 int error = PA_ERR_INTERNAL, r;
508 CHECK_VALIDITY_RETURN_ANY(rerror, !server || *server, PA_ERR_INVALID, NULL);
509 CHECK_VALIDITY_RETURN_ANY(rerror, dir == PA_STREAM_PLAYBACK || dir == PA_STREAM_RECORD, PA_ERR_INVALID, NULL);
510 CHECK_VALIDITY_RETURN_ANY(rerror, !dev || *dev, PA_ERR_INVALID, NULL);
511 CHECK_VALIDITY_RETURN_ANY(rerror, ss && pa_sample_spec_valid(ss), PA_ERR_INVALID, NULL);
512 CHECK_VALIDITY_RETURN_ANY(rerror, !map || (pa_channel_map_valid(map) && map->channels == ss->channels), PA_ERR_INVALID, NULL);
514 p = pa_xnew0(pa_simple, 1);
517 if (!(p->mainloop = pa_threaded_mainloop_new()))
520 if (!(p->context = pa_context_new(pa_threaded_mainloop_get_api(p->mainloop), name)))
523 pa_context_set_state_callback(p->context, context_state_cb, p);
525 if (pa_context_connect(p->context, server, 0, NULL) < 0) {
526 error = pa_context_errno(p->context);
530 pa_threaded_mainloop_lock(p->mainloop);
532 if (pa_threaded_mainloop_start(p->mainloop) < 0)
533 goto unlock_and_fail;
536 pa_context_state_t state;
538 state = pa_context_get_state(p->context);
540 if (state == PA_CONTEXT_READY)
543 if (!PA_CONTEXT_IS_GOOD(state)) {
544 error = pa_context_errno(p->context);
545 goto unlock_and_fail;
548 /* Wait until the context is ready */
549 pa_threaded_mainloop_wait(p->mainloop);
552 if (!(p->stream = pa_stream_new_with_proplist(p->context, stream_name, ss, map, proplist))) {
553 error = pa_context_errno(p->context);
554 goto unlock_and_fail;
557 pa_stream_set_state_callback(p->stream, stream_state_cb, p);
558 pa_stream_set_read_callback(p->stream, stream_request_cb, p);
559 pa_stream_set_write_callback(p->stream, stream_request_cb, p);
560 pa_stream_set_latency_update_callback(p->stream, stream_latency_update_cb, p);
562 if (dir == PA_STREAM_PLAYBACK)
563 r = pa_stream_connect_playback(p->stream, dev, attr,
564 PA_STREAM_INTERPOLATE_TIMING
565 |PA_STREAM_ADJUST_LATENCY
566 |PA_STREAM_AUTO_TIMING_UPDATE, NULL, NULL);
568 r = pa_stream_connect_record(p->stream, dev, attr,
569 PA_STREAM_INTERPOLATE_TIMING
570 |PA_STREAM_ADJUST_LATENCY
571 |PA_STREAM_AUTO_TIMING_UPDATE
572 |PA_STREAM_START_CORKED);
575 error = pa_context_errno(p->context);
576 goto unlock_and_fail;
580 pa_stream_state_t state;
582 state = pa_stream_get_state(p->stream);
584 if (state == PA_STREAM_READY)
587 if (!PA_STREAM_IS_GOOD(state)) {
588 error = pa_context_errno(p->context);
589 goto unlock_and_fail;
592 /* Wait until the stream is ready */
593 pa_threaded_mainloop_wait(p->mainloop);
596 pa_threaded_mainloop_unlock(p->mainloop);
601 pa_threaded_mainloop_unlock(p->mainloop);
610 int pa_simple_mute(pa_simple *p, int mute, int *rerror) {
611 pa_operation *o = NULL;
616 CHECK_VALIDITY_RETURN_ANY(rerror, p->direction == PA_STREAM_PLAYBACK, PA_ERR_BADSTATE, -1);
618 pa_threaded_mainloop_lock(p->mainloop);
619 CHECK_DEAD_GOTO(p, rerror, unlock_and_fail);
621 CHECK_SUCCESS_GOTO(p, rerror, ((idx = pa_stream_get_index (p->stream)) != PA_INVALID_INDEX), unlock_and_fail);
624 o = pa_context_set_sink_input_mute (p->context, idx, mute, success_context_cb, p);
625 CHECK_SUCCESS_GOTO(p, rerror, o, unlock_and_fail);
627 p->operation_success = 0;
628 while (pa_operation_get_state(o) == PA_OPERATION_RUNNING) {
629 pa_threaded_mainloop_wait(p->mainloop);
630 CHECK_DEAD_GOTO(p, rerror, unlock_and_fail);
632 CHECK_SUCCESS_GOTO(p, rerror, p->operation_success, unlock_and_fail);
634 pa_operation_unref(o);
635 pa_threaded_mainloop_unlock(p->mainloop);
642 pa_operation_cancel(o);
643 pa_operation_unref(o);
646 pa_threaded_mainloop_unlock(p->mainloop);
650 int pa_simple_get_stream_index(pa_simple *p, unsigned int *idx, int *rerror) {
652 CHECK_VALIDITY_RETURN_ANY(rerror, idx != NULL, PA_ERR_INVALID, -1);
654 pa_threaded_mainloop_lock(p->mainloop);
656 CHECK_DEAD_GOTO(p, rerror, unlock_and_fail);
658 *idx = pa_stream_get_index(p->stream);
660 pa_threaded_mainloop_unlock(p->mainloop);
664 pa_threaded_mainloop_unlock(p->mainloop);
668 int pa_simple_set_volume(pa_simple *p, int volume, int *rerror) {
669 pa_operation *o = NULL;
676 CHECK_VALIDITY_RETURN_ANY(rerror, p->direction == PA_STREAM_PLAYBACK, PA_ERR_BADSTATE, -1);
677 CHECK_VALIDITY_RETURN_ANY(rerror, volume >= 0, PA_ERR_INVALID, -1);
678 CHECK_VALIDITY_RETURN_ANY(rerror, volume <= 65535, PA_ERR_INVALID, -1);
680 pa_threaded_mainloop_lock(p->mainloop);
681 CHECK_DEAD_GOTO(p, rerror, unlock_and_fail);
683 CHECK_SUCCESS_GOTO(p, rerror, ((idx = pa_stream_get_index (p->stream)) != PA_INVALID_INDEX), unlock_and_fail);
687 pa_cvolume_set(&cv, s->sample_spec.channels, volume);
689 o = pa_context_set_sink_input_volume (p->context, idx, &cv, success_context_cb, p);
691 CHECK_SUCCESS_GOTO(p, rerror, o, unlock_and_fail);
693 p->operation_success = 0;
694 while (pa_operation_get_state(o) == PA_OPERATION_RUNNING) {
695 pa_threaded_mainloop_wait(p->mainloop);
696 CHECK_DEAD_GOTO(p, rerror, unlock_and_fail);
698 CHECK_SUCCESS_GOTO(p, rerror, p->operation_success, unlock_and_fail);
700 pa_operation_unref(o);
701 pa_threaded_mainloop_unlock(p->mainloop);
708 pa_operation_cancel(o);
709 pa_operation_unref(o);
712 pa_threaded_mainloop_unlock(p->mainloop);
716 int pa_simple_cork(pa_simple *p, int cork, int *rerror) {
717 pa_operation *o = NULL;
721 pa_threaded_mainloop_lock(p->mainloop);
722 CHECK_DEAD_GOTO(p, rerror, unlock_and_fail);
724 o = pa_stream_cork(p->stream, cork, success_cb, p);
725 CHECK_SUCCESS_GOTO(p, rerror, o, unlock_and_fail);
727 p->operation_success = 0;
728 while (pa_operation_get_state(o) == PA_OPERATION_RUNNING) {
729 pa_threaded_mainloop_wait(p->mainloop);
730 CHECK_DEAD_GOTO(p, rerror, unlock_and_fail);
732 CHECK_SUCCESS_GOTO(p, rerror, p->operation_success, unlock_and_fail);
734 pa_operation_unref(o);
735 pa_threaded_mainloop_unlock(p->mainloop);
742 pa_operation_cancel(o);
743 pa_operation_unref(o);
746 pa_threaded_mainloop_unlock(p->mainloop);
750 int pa_simple_is_corked(pa_simple *p) {
754 pa_threaded_mainloop_lock(p->mainloop);
756 is_cork = pa_stream_is_corked(p->stream);
758 pa_threaded_mainloop_unlock(p->mainloop);