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 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
, 0, 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;