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/native-common.h>
36 #include <pulsecore/log.h>
37 #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 stream_success_context_cb(pa_stream *s, 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 success_context_cb(pa_context *c, int success, void *userdata) {
117 pa_simple *p = userdata;
121 p->operation_success = success;
122 pa_threaded_mainloop_signal(p->mainloop, 0);
125 static void stream_state_cb(pa_stream *s, void * userdata) {
126 pa_simple *p = userdata;
130 switch (pa_stream_get_state(s)) {
132 case PA_STREAM_READY:
133 case PA_STREAM_FAILED:
134 case PA_STREAM_TERMINATED:
135 pa_threaded_mainloop_signal(p->mainloop, 0);
138 case PA_STREAM_UNCONNECTED:
139 case PA_STREAM_CREATING:
144 static void stream_request_cb(pa_stream *s, size_t length, void *userdata) {
145 pa_simple *p = userdata;
148 pa_threaded_mainloop_signal(p->mainloop, 0);
151 static void stream_latency_update_cb(pa_stream *s, void *userdata) {
152 pa_simple *p = userdata;
156 pa_threaded_mainloop_signal(p->mainloop, 0);
159 pa_simple* pa_simple_new(
162 pa_stream_direction_t dir,
164 const char *stream_name,
165 const pa_sample_spec *ss,
166 const pa_channel_map *map,
167 const pa_buffer_attr *attr,
171 int error = PA_ERR_INTERNAL, r;
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)
179 p = pa_xnew0(pa_simple, 1);
182 if (!(p->mainloop = pa_threaded_mainloop_new()))
185 if (!(p->context = pa_context_new(pa_threaded_mainloop_get_api(p->mainloop), name)))
188 pa_context_set_state_callback(p->context, context_state_cb, p);
190 if (pa_context_connect(p->context, server, 0, NULL) < 0) {
191 error = pa_context_errno(p->context);
195 pa_threaded_mainloop_lock(p->mainloop);
197 if (pa_threaded_mainloop_start(p->mainloop) < 0)
198 goto unlock_and_fail;
201 pa_context_state_t state;
203 state = pa_context_get_state(p->context);
205 if (state == PA_CONTEXT_READY)
208 if (!PA_CONTEXT_IS_GOOD(state)) {
209 error = pa_context_errno(p->context);
210 goto unlock_and_fail;
213 /* Wait until the context is ready */
214 pa_threaded_mainloop_wait(p->mainloop);
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;
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);
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);
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);
239 error = pa_context_errno(p->context);
240 goto unlock_and_fail;
244 pa_stream_state_t state;
246 state = pa_stream_get_state(p->stream);
248 if (state == PA_STREAM_READY)
251 if (!PA_STREAM_IS_GOOD(state)) {
252 error = pa_context_errno(p->context);
253 goto unlock_and_fail;
256 /* Wait until the stream is ready */
257 pa_threaded_mainloop_wait(p->mainloop);
260 pa_threaded_mainloop_unlock(p->mainloop);
265 pa_threaded_mainloop_unlock(p->mainloop);
274 pa_simple* pa_simple_new_proplist(
277 pa_stream_direction_t dir,
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,
287 int error = PA_ERR_INTERNAL, r;
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)
295 p = pa_xnew0(pa_simple, 1);
298 if (!(p->mainloop = pa_threaded_mainloop_new()))
301 if (!(p->context = pa_context_new(pa_threaded_mainloop_get_api(p->mainloop), name)))
304 pa_context_set_state_callback(p->context, context_state_cb, p);
306 if (pa_context_connect(p->context, server, 0, NULL) < 0) {
307 error = pa_context_errno(p->context);
311 pa_threaded_mainloop_lock(p->mainloop);
313 if (pa_threaded_mainloop_start(p->mainloop) < 0)
314 goto unlock_and_fail;
317 pa_context_state_t state;
319 state = pa_context_get_state(p->context);
321 if (state == PA_CONTEXT_READY)
324 if (!PA_CONTEXT_IS_GOOD(state)) {
325 error = pa_context_errno(p->context);
326 goto unlock_and_fail;
329 /* Wait until the context is ready */
330 pa_threaded_mainloop_wait(p->mainloop);
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;
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);
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);
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);
356 error = pa_context_errno(p->context);
357 goto unlock_and_fail;
361 pa_stream_state_t state;
363 state = pa_stream_get_state(p->stream);
365 if (state == PA_STREAM_READY)
368 if (!PA_STREAM_IS_GOOD(state)) {
369 error = pa_context_errno(p->context);
370 goto unlock_and_fail;
373 /* Wait until the stream is ready */
374 pa_threaded_mainloop_wait(p->mainloop);
377 pa_threaded_mainloop_unlock(p->mainloop);
382 pa_threaded_mainloop_unlock(p->mainloop);
390 void pa_simple_free(pa_simple *s) {
394 pa_threaded_mainloop_stop(s->mainloop);
397 pa_stream_unref(s->stream);
400 pa_context_disconnect(s->context);
401 pa_context_unref(s->context);
405 pa_threaded_mainloop_free(s->mainloop);
410 int pa_simple_write(pa_simple *p, const void*data, size_t length, int *rerror) {
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);
417 pa_threaded_mainloop_lock(p->mainloop);
419 CHECK_DEAD_GOTO(p, rerror, unlock_and_fail);
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);
430 CHECK_SUCCESS_GOTO(p, rerror, l != (size_t) -1, unlock_and_fail);
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);
438 data = (const uint8_t*) data + l;
442 pa_threaded_mainloop_unlock(p->mainloop);
446 pa_threaded_mainloop_unlock(p->mainloop);
450 int pa_simple_read(pa_simple *p, void*data, size_t length, int *rerror) {
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);
457 pa_threaded_mainloop_lock(p->mainloop);
459 CHECK_DEAD_GOTO(p, rerror, unlock_and_fail);
464 while (!p->read_data) {
467 r = pa_stream_peek(p->stream, &p->read_data, &p->read_length);
468 CHECK_SUCCESS_GOTO(p, rerror, r == 0, unlock_and_fail);
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);
482 l = p->read_length < length ? p->read_length : length;
483 memcpy(data, (const uint8_t*) p->read_data+p->read_index, l);
485 data = (uint8_t*) data + l;
491 if (!p->read_length) {
494 r = pa_stream_drop(p->stream);
499 CHECK_SUCCESS_GOTO(p, rerror, r == 0, unlock_and_fail);
503 pa_threaded_mainloop_unlock(p->mainloop);
507 pa_threaded_mainloop_unlock(p->mainloop);
511 static void success_cb(pa_stream *s, int success, void *userdata) {
512 pa_simple *p = userdata;
517 p->operation_success = success;
518 pa_threaded_mainloop_signal(p->mainloop, 0);
521 int pa_simple_drain(pa_simple *p, int *rerror) {
522 pa_operation *o = NULL;
526 CHECK_VALIDITY_RETURN_ANY(rerror, p->direction == PA_STREAM_PLAYBACK, PA_ERR_BADSTATE, -1);
528 pa_threaded_mainloop_lock(p->mainloop);
529 CHECK_DEAD_GOTO(p, rerror, unlock_and_fail);
531 o = pa_stream_drain(p->stream, success_cb, p);
532 CHECK_SUCCESS_GOTO(p, rerror, o, unlock_and_fail);
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);
539 CHECK_SUCCESS_GOTO(p, rerror, p->operation_success, unlock_and_fail);
541 pa_operation_unref(o);
542 pa_threaded_mainloop_unlock(p->mainloop);
549 pa_operation_cancel(o);
550 pa_operation_unref(o);
553 pa_threaded_mainloop_unlock(p->mainloop);
557 int pa_simple_flush(pa_simple *p, int *rerror) {
558 pa_operation *o = NULL;
562 pa_threaded_mainloop_lock(p->mainloop);
563 CHECK_DEAD_GOTO(p, rerror, unlock_and_fail);
565 o = pa_stream_flush(p->stream, success_cb, p);
566 CHECK_SUCCESS_GOTO(p, rerror, o, unlock_and_fail);
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);
573 CHECK_SUCCESS_GOTO(p, rerror, p->operation_success, unlock_and_fail);
575 pa_operation_unref(o);
576 pa_threaded_mainloop_unlock(p->mainloop);
583 pa_operation_cancel(o);
584 pa_operation_unref(o);
587 pa_threaded_mainloop_unlock(p->mainloop);
591 int pa_simple_get_stream_index(pa_simple *p, unsigned int *idx, int *rerror) {
593 CHECK_VALIDITY_RETURN_ANY(rerror, idx != NULL, PA_ERR_INVALID, -1);
595 pa_threaded_mainloop_lock(p->mainloop);
597 CHECK_DEAD_GOTO(p, rerror, unlock_and_fail);
599 *idx = pa_stream_get_index(p->stream);
601 pa_threaded_mainloop_unlock(p->mainloop);
605 pa_threaded_mainloop_unlock(p->mainloop);
609 pa_usec_t pa_simple_get_latency(pa_simple *p, int *rerror) {
615 pa_threaded_mainloop_lock(p->mainloop);
618 CHECK_DEAD_GOTO(p, rerror, unlock_and_fail);
620 if (pa_stream_get_latency(p->stream, &t, &negative) >= 0)
623 CHECK_SUCCESS_GOTO(p, rerror, pa_context_errno(p->context) == PA_ERR_NODATA, unlock_and_fail);
625 /* Wait until latency data is available again */
626 pa_threaded_mainloop_wait(p->mainloop);
629 pa_threaded_mainloop_unlock(p->mainloop);
631 return negative ? 0 : t;
635 pa_threaded_mainloop_unlock(p->mainloop);
636 return (pa_usec_t) -1;