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>
42 pa_threaded_mainloop
*mainloop
;
45 pa_stream_direction_t direction
;
47 const void *read_data
;
48 size_t read_index
, read_length
;
50 int operation_success
;
53 #define CHECK_VALIDITY_RETURN_ANY(rerror, expression, error, ret) do { \
54 if (!(expression)) { \
61 #define CHECK_SUCCESS_GOTO(p, rerror, expression, label) do { \
62 if (!(expression)) { \
64 *(rerror) = pa_context_errno((p)->context); \
69 #define CHECK_DEAD_GOTO(p, rerror, label) do { \
70 if (!(p)->context || pa_context_get_state((p)->context) != PA_CONTEXT_READY || \
71 !(p)->stream || pa_stream_get_state((p)->stream) != PA_STREAM_READY) { \
72 if (((p)->context && pa_context_get_state((p)->context) == PA_CONTEXT_FAILED) || \
73 ((p)->stream && pa_stream_get_state((p)->stream) == PA_STREAM_FAILED)) { \
75 *(rerror) = pa_context_errno((p)->context); \
78 *(rerror) = PA_ERR_BADSTATE; \
83 static void context_state_cb(pa_context
*c
, void *userdata
) {
84 pa_simple
*p
= userdata
;
88 switch (pa_context_get_state(c
)) {
89 case PA_CONTEXT_READY
:
90 case PA_CONTEXT_TERMINATED
:
91 case PA_CONTEXT_FAILED
:
92 pa_threaded_mainloop_signal(p
->mainloop
, 0);
95 case PA_CONTEXT_UNCONNECTED
:
96 case PA_CONTEXT_CONNECTING
:
97 case PA_CONTEXT_AUTHORIZING
:
98 case PA_CONTEXT_SETTING_NAME
:
103 static void stream_state_cb(pa_stream
*s
, void * userdata
) {
104 pa_simple
*p
= userdata
;
108 switch (pa_stream_get_state(s
)) {
110 case PA_STREAM_READY
:
111 case PA_STREAM_FAILED
:
112 case PA_STREAM_TERMINATED
:
113 pa_threaded_mainloop_signal(p
->mainloop
, 0);
116 case PA_STREAM_UNCONNECTED
:
117 case PA_STREAM_CREATING
:
122 static void stream_request_cb(pa_stream
*s
, size_t length
, void *userdata
) {
123 pa_simple
*p
= userdata
;
126 pa_threaded_mainloop_signal(p
->mainloop
, 0);
129 static void stream_latency_update_cb(pa_stream
*s
, void *userdata
) {
130 pa_simple
*p
= userdata
;
134 pa_threaded_mainloop_signal(p
->mainloop
, 0);
137 pa_simple
* pa_simple_new(
140 pa_stream_direction_t dir
,
142 const char *stream_name
,
143 const pa_sample_spec
*ss
,
144 const pa_channel_map
*map
,
145 const pa_buffer_attr
*attr
,
149 int error
= PA_ERR_INTERNAL
, r
;
151 CHECK_VALIDITY_RETURN_ANY(rerror
, !server
|| *server
, PA_ERR_INVALID
, NULL
);
152 CHECK_VALIDITY_RETURN_ANY(rerror
, dir
== PA_STREAM_PLAYBACK
|| dir
== PA_STREAM_RECORD
, PA_ERR_INVALID
, NULL
);
153 CHECK_VALIDITY_RETURN_ANY(rerror
, !dev
|| *dev
, PA_ERR_INVALID
, NULL
);
154 CHECK_VALIDITY_RETURN_ANY(rerror
, ss
&& pa_sample_spec_valid(ss
), PA_ERR_INVALID
, NULL
);
155 CHECK_VALIDITY_RETURN_ANY(rerror
, !map
|| (pa_channel_map_valid(map
) && map
->channels
== ss
->channels
), PA_ERR_INVALID
, NULL
)
157 p
= pa_xnew(pa_simple
, 1);
162 p
->read_index
= p
->read_length
= 0;
164 if (!(p
->mainloop
= pa_threaded_mainloop_new()))
167 if (!(p
->context
= pa_context_new(pa_threaded_mainloop_get_api(p
->mainloop
), name
)))
170 pa_context_set_state_callback(p
->context
, context_state_cb
, p
);
172 if (pa_context_connect(p
->context
, server
, 0, NULL
) < 0) {
173 error
= pa_context_errno(p
->context
);
177 pa_threaded_mainloop_lock(p
->mainloop
);
179 if (pa_threaded_mainloop_start(p
->mainloop
) < 0)
180 goto unlock_and_fail
;
182 /* Wait until the context is ready */
183 pa_threaded_mainloop_wait(p
->mainloop
);
185 if (pa_context_get_state(p
->context
) != PA_CONTEXT_READY
) {
186 error
= pa_context_errno(p
->context
);
187 goto unlock_and_fail
;
190 if (!(p
->stream
= pa_stream_new(p
->context
, stream_name
, ss
, map
))) {
191 error
= pa_context_errno(p
->context
);
192 goto unlock_and_fail
;
195 pa_stream_set_state_callback(p
->stream
, stream_state_cb
, p
);
196 pa_stream_set_read_callback(p
->stream
, stream_request_cb
, p
);
197 pa_stream_set_write_callback(p
->stream
, stream_request_cb
, p
);
198 pa_stream_set_latency_update_callback(p
->stream
, stream_latency_update_cb
, p
);
200 if (dir
== PA_STREAM_PLAYBACK
)
201 r
= pa_stream_connect_playback(p
->stream
, dev
, attr
, PA_STREAM_INTERPOLATE_TIMING
|PA_STREAM_AUTO_TIMING_UPDATE
, NULL
, NULL
);
203 r
= pa_stream_connect_record(p
->stream
, dev
, attr
, PA_STREAM_INTERPOLATE_TIMING
|PA_STREAM_AUTO_TIMING_UPDATE
);
206 error
= pa_context_errno(p
->context
);
207 goto unlock_and_fail
;
210 /* Wait until the stream is ready */
211 pa_threaded_mainloop_wait(p
->mainloop
);
213 /* Wait until the stream is ready */
214 if (pa_stream_get_state(p
->stream
) != PA_STREAM_READY
) {
215 error
= pa_context_errno(p
->context
);
216 goto unlock_and_fail
;
219 pa_threaded_mainloop_unlock(p
->mainloop
);
224 pa_threaded_mainloop_unlock(p
->mainloop
);
233 void pa_simple_free(pa_simple
*s
) {
237 pa_threaded_mainloop_stop(s
->mainloop
);
240 pa_stream_unref(s
->stream
);
243 pa_context_unref(s
->context
);
246 pa_threaded_mainloop_free(s
->mainloop
);
251 int pa_simple_write(pa_simple
*p
, const void*data
, size_t length
, int *rerror
) {
254 CHECK_VALIDITY_RETURN_ANY(rerror
, p
->direction
== PA_STREAM_PLAYBACK
, PA_ERR_BADSTATE
, -1);
255 CHECK_VALIDITY_RETURN_ANY(rerror
, data
&& length
, PA_ERR_INVALID
, -1);
257 pa_threaded_mainloop_lock(p
->mainloop
);
259 CHECK_DEAD_GOTO(p
, rerror
, unlock_and_fail
);
265 while (!(l
= pa_stream_writable_size(p
->stream
))) {
266 pa_threaded_mainloop_wait(p
->mainloop
);
267 CHECK_DEAD_GOTO(p
, rerror
, unlock_and_fail
);
270 CHECK_SUCCESS_GOTO(p
, rerror
, l
!= (size_t) -1, unlock_and_fail
);
275 r
= pa_stream_write(p
->stream
, data
, l
, NULL
, 0LL, PA_SEEK_RELATIVE
);
276 CHECK_SUCCESS_GOTO(p
, rerror
, r
>= 0, unlock_and_fail
);
278 data
= (const uint8_t*) data
+ l
;
282 pa_threaded_mainloop_unlock(p
->mainloop
);
286 pa_threaded_mainloop_unlock(p
->mainloop
);
290 int pa_simple_read(pa_simple
*p
, void*data
, size_t length
, int *rerror
) {
293 CHECK_VALIDITY_RETURN_ANY(rerror
, p
->direction
== PA_STREAM_RECORD
, PA_ERR_BADSTATE
, -1);
294 CHECK_VALIDITY_RETURN_ANY(rerror
, data
&& length
, PA_ERR_INVALID
, -1);
296 pa_threaded_mainloop_lock(p
->mainloop
);
298 CHECK_DEAD_GOTO(p
, rerror
, unlock_and_fail
);
303 while (!p
->read_data
) {
306 r
= pa_stream_peek(p
->stream
, &p
->read_data
, &p
->read_length
);
307 CHECK_SUCCESS_GOTO(p
, rerror
, r
== 0, unlock_and_fail
);
310 pa_threaded_mainloop_wait(p
->mainloop
);
311 CHECK_DEAD_GOTO(p
, rerror
, unlock_and_fail
);
316 l
= p
->read_length
< length
? p
->read_length
: length
;
317 memcpy(data
, (const uint8_t*) p
->read_data
+p
->read_index
, l
);
319 data
= (uint8_t*) data
+ l
;
325 if (!p
->read_length
) {
328 r
= pa_stream_drop(p
->stream
);
333 CHECK_SUCCESS_GOTO(p
, rerror
, r
== 0, unlock_and_fail
);
337 pa_threaded_mainloop_unlock(p
->mainloop
);
341 pa_threaded_mainloop_unlock(p
->mainloop
);
345 static void success_cb(pa_stream
*s
, int success
, void *userdata
) {
346 pa_simple
*p
= userdata
;
351 p
->operation_success
= success
;
352 pa_threaded_mainloop_signal(p
->mainloop
, 0);
355 int pa_simple_drain(pa_simple
*p
, int *rerror
) {
356 pa_operation
*o
= NULL
;
360 CHECK_VALIDITY_RETURN_ANY(rerror
, p
->direction
== PA_STREAM_PLAYBACK
, PA_ERR_BADSTATE
, -1);
362 pa_threaded_mainloop_lock(p
->mainloop
);
363 CHECK_DEAD_GOTO(p
, rerror
, unlock_and_fail
);
365 o
= pa_stream_drain(p
->stream
, success_cb
, p
);
366 CHECK_SUCCESS_GOTO(p
, rerror
, o
, unlock_and_fail
);
368 p
->operation_success
= 0;
369 while (pa_operation_get_state(o
) != PA_OPERATION_DONE
) {
370 pa_threaded_mainloop_wait(p
->mainloop
);
371 CHECK_DEAD_GOTO(p
, rerror
, unlock_and_fail
);
373 CHECK_SUCCESS_GOTO(p
, rerror
, p
->operation_success
, unlock_and_fail
);
375 pa_operation_unref(o
);
376 pa_threaded_mainloop_unlock(p
->mainloop
);
383 pa_operation_cancel(o
);
384 pa_operation_unref(o
);
387 pa_threaded_mainloop_unlock(p
->mainloop
);
391 int pa_simple_flush(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_flush(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_DONE
) {
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 pa_usec_t
pa_simple_get_latency(pa_simple
*p
, int *rerror
) {
433 pa_threaded_mainloop_lock(p
->mainloop
);
436 CHECK_DEAD_GOTO(p
, rerror
, unlock_and_fail
);
438 if (pa_stream_get_latency(p
->stream
, &t
, &negative
) >= 0)
441 CHECK_SUCCESS_GOTO(p
, rerror
, pa_context_errno(p
->context
) == PA_ERR_NODATA
, unlock_and_fail
);
443 /* Wait until latency data is available again */
444 pa_threaded_mainloop_wait(p
->mainloop
);
447 pa_threaded_mainloop_unlock(p
->mainloop
);
449 return negative
? 0 : t
;
453 pa_threaded_mainloop_unlock(p
->mainloop
);
454 return (pa_usec_t
) -1;