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>
41 pa_threaded_mainloop
*mainloop
;
44 pa_stream_direction_t direction
;
46 const void *read_data
;
47 size_t read_index
, read_length
;
49 int operation_success
;
52 #define CHECK_VALIDITY_RETURN_ANY(rerror, expression, error, ret) \
54 if (!(expression)) { \
61 #define CHECK_SUCCESS_GOTO(p, rerror, expression, label) \
63 if (!(expression)) { \
65 *(rerror) = pa_context_errno((p)->context); \
70 #define CHECK_DEAD_GOTO(p, rerror, label) \
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)) { \
77 *(rerror) = pa_context_errno((p)->context); \
80 *(rerror) = PA_ERR_BADSTATE; \
85 static void context_state_cb(pa_context
*c
, void *userdata
) {
86 pa_simple
*p
= userdata
;
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);
97 case PA_CONTEXT_UNCONNECTED
:
98 case PA_CONTEXT_CONNECTING
:
99 case PA_CONTEXT_AUTHORIZING
:
100 case PA_CONTEXT_SETTING_NAME
:
105 static void stream_state_cb(pa_stream
*s
, void * userdata
) {
106 pa_simple
*p
= userdata
;
110 switch (pa_stream_get_state(s
)) {
112 case PA_STREAM_READY
:
113 case PA_STREAM_FAILED
:
114 case PA_STREAM_TERMINATED
:
115 pa_threaded_mainloop_signal(p
->mainloop
, 0);
118 case PA_STREAM_UNCONNECTED
:
119 case PA_STREAM_CREATING
:
124 static void stream_request_cb(pa_stream
*s
, size_t length
, void *userdata
) {
125 pa_simple
*p
= userdata
;
128 pa_threaded_mainloop_signal(p
->mainloop
, 0);
131 static void stream_latency_update_cb(pa_stream
*s
, void *userdata
) {
132 pa_simple
*p
= userdata
;
136 pa_threaded_mainloop_signal(p
->mainloop
, 0);
139 pa_simple
* pa_simple_new(
142 pa_stream_direction_t dir
,
144 const char *stream_name
,
145 const pa_sample_spec
*ss
,
146 const pa_channel_map
*map
,
147 const pa_buffer_attr
*attr
,
151 int error
= PA_ERR_INTERNAL
, r
;
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
)
159 p
= pa_xnew0(pa_simple
, 1);
162 if (!(p
->mainloop
= pa_threaded_mainloop_new()))
165 if (!(p
->context
= pa_context_new(pa_threaded_mainloop_get_api(p
->mainloop
), name
)))
168 pa_context_set_state_callback(p
->context
, context_state_cb
, p
);
170 if (pa_context_connect(p
->context
, server
, 0, NULL
) < 0) {
171 error
= pa_context_errno(p
->context
);
175 pa_threaded_mainloop_lock(p
->mainloop
);
177 if (pa_threaded_mainloop_start(p
->mainloop
) < 0)
178 goto unlock_and_fail
;
181 pa_context_state_t state
;
183 state
= pa_context_get_state(p
->context
);
185 if (state
== PA_CONTEXT_READY
)
188 if (!PA_CONTEXT_IS_GOOD(state
)) {
189 error
= pa_context_errno(p
->context
);
190 goto unlock_and_fail
;
193 /* Wait until the context is ready */
194 pa_threaded_mainloop_wait(p
->mainloop
);
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
;
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
);
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
);
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
);
219 error
= pa_context_errno(p
->context
);
220 goto unlock_and_fail
;
224 pa_stream_state_t state
;
226 state
= pa_stream_get_state(p
->stream
);
228 if (state
== PA_STREAM_READY
)
231 if (!PA_STREAM_IS_GOOD(state
)) {
232 error
= pa_context_errno(p
->context
);
233 goto unlock_and_fail
;
236 /* Wait until the stream is ready */
237 pa_threaded_mainloop_wait(p
->mainloop
);
240 pa_threaded_mainloop_unlock(p
->mainloop
);
245 pa_threaded_mainloop_unlock(p
->mainloop
);
254 void pa_simple_free(pa_simple
*s
) {
258 pa_threaded_mainloop_stop(s
->mainloop
);
261 pa_stream_unref(s
->stream
);
264 pa_context_disconnect(s
->context
);
265 pa_context_unref(s
->context
);
269 pa_threaded_mainloop_free(s
->mainloop
);
274 int pa_simple_write(pa_simple
*p
, const void*data
, size_t length
, int *rerror
) {
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);
281 pa_threaded_mainloop_lock(p
->mainloop
);
283 CHECK_DEAD_GOTO(p
, rerror
, unlock_and_fail
);
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
);
294 CHECK_SUCCESS_GOTO(p
, rerror
, l
!= (size_t) -1, unlock_and_fail
);
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
);
302 data
= (const uint8_t*) data
+ l
;
306 pa_threaded_mainloop_unlock(p
->mainloop
);
310 pa_threaded_mainloop_unlock(p
->mainloop
);
314 int pa_simple_read(pa_simple
*p
, void*data
, size_t length
, int *rerror
) {
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);
321 pa_threaded_mainloop_lock(p
->mainloop
);
323 CHECK_DEAD_GOTO(p
, rerror
, unlock_and_fail
);
328 while (!p
->read_data
) {
331 r
= pa_stream_peek(p
->stream
, &p
->read_data
, &p
->read_length
);
332 CHECK_SUCCESS_GOTO(p
, rerror
, r
== 0, unlock_and_fail
);
334 if (p
->read_length
<= 0) {
335 pa_threaded_mainloop_wait(p
->mainloop
);
336 CHECK_DEAD_GOTO(p
, rerror
, unlock_and_fail
);
337 } else if (!p
->read_data
) {
338 /* There's a hole in the stream, skip it. We could generate
339 * silence, but that wouldn't work for compressed streams. */
340 r
= pa_stream_drop(p
->stream
);
341 CHECK_SUCCESS_GOTO(p
, rerror
, r
== 0, unlock_and_fail
);
346 l
= p
->read_length
< length
? p
->read_length
: length
;
347 memcpy(data
, (const uint8_t*) p
->read_data
+p
->read_index
, l
);
349 data
= (uint8_t*) data
+ l
;
355 if (!p
->read_length
) {
358 r
= pa_stream_drop(p
->stream
);
363 CHECK_SUCCESS_GOTO(p
, rerror
, r
== 0, unlock_and_fail
);
367 pa_threaded_mainloop_unlock(p
->mainloop
);
371 pa_threaded_mainloop_unlock(p
->mainloop
);
375 static void success_cb(pa_stream
*s
, int success
, void *userdata
) {
376 pa_simple
*p
= userdata
;
381 p
->operation_success
= success
;
382 pa_threaded_mainloop_signal(p
->mainloop
, 0);
385 int pa_simple_drain(pa_simple
*p
, int *rerror
) {
386 pa_operation
*o
= NULL
;
390 CHECK_VALIDITY_RETURN_ANY(rerror
, p
->direction
== PA_STREAM_PLAYBACK
, PA_ERR_BADSTATE
, -1);
392 pa_threaded_mainloop_lock(p
->mainloop
);
393 CHECK_DEAD_GOTO(p
, rerror
, unlock_and_fail
);
395 o
= pa_stream_drain(p
->stream
, success_cb
, p
);
396 CHECK_SUCCESS_GOTO(p
, rerror
, o
, unlock_and_fail
);
398 p
->operation_success
= 0;
399 while (pa_operation_get_state(o
) == PA_OPERATION_RUNNING
) {
400 pa_threaded_mainloop_wait(p
->mainloop
);
401 CHECK_DEAD_GOTO(p
, rerror
, unlock_and_fail
);
403 CHECK_SUCCESS_GOTO(p
, rerror
, p
->operation_success
, unlock_and_fail
);
405 pa_operation_unref(o
);
406 pa_threaded_mainloop_unlock(p
->mainloop
);
413 pa_operation_cancel(o
);
414 pa_operation_unref(o
);
417 pa_threaded_mainloop_unlock(p
->mainloop
);
421 int pa_simple_flush(pa_simple
*p
, int *rerror
) {
422 pa_operation
*o
= NULL
;
426 pa_threaded_mainloop_lock(p
->mainloop
);
427 CHECK_DEAD_GOTO(p
, rerror
, unlock_and_fail
);
429 o
= pa_stream_flush(p
->stream
, success_cb
, p
);
430 CHECK_SUCCESS_GOTO(p
, rerror
, o
, unlock_and_fail
);
432 p
->operation_success
= 0;
433 while (pa_operation_get_state(o
) == PA_OPERATION_RUNNING
) {
434 pa_threaded_mainloop_wait(p
->mainloop
);
435 CHECK_DEAD_GOTO(p
, rerror
, unlock_and_fail
);
437 CHECK_SUCCESS_GOTO(p
, rerror
, p
->operation_success
, unlock_and_fail
);
439 pa_operation_unref(o
);
440 pa_threaded_mainloop_unlock(p
->mainloop
);
447 pa_operation_cancel(o
);
448 pa_operation_unref(o
);
451 pa_threaded_mainloop_unlock(p
->mainloop
);
455 pa_usec_t
pa_simple_get_latency(pa_simple
*p
, int *rerror
) {
461 pa_threaded_mainloop_lock(p
->mainloop
);
464 CHECK_DEAD_GOTO(p
, rerror
, unlock_and_fail
);
466 if (pa_stream_get_latency(p
->stream
, &t
, &negative
) >= 0)
469 CHECK_SUCCESS_GOTO(p
, rerror
, pa_context_errno(p
->context
) == PA_ERR_NODATA
, unlock_and_fail
);
471 /* Wait until latency data is available again */
472 pa_threaded_mainloop_wait(p
->mainloop
);
475 pa_threaded_mainloop_unlock(p
->mainloop
);
477 return negative
? 0 : t
;
481 pa_threaded_mainloop_unlock(p
->mainloop
);
482 return (pa_usec_t
) -1;