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
);
335 pa_threaded_mainloop_wait(p
->mainloop
);
336 CHECK_DEAD_GOTO(p
, rerror
, unlock_and_fail
);
341 l
= p
->read_length
< length
? p
->read_length
: length
;
342 memcpy(data
, (const uint8_t*) p
->read_data
+p
->read_index
, l
);
344 data
= (uint8_t*) data
+ l
;
350 if (!p
->read_length
) {
353 r
= pa_stream_drop(p
->stream
);
358 CHECK_SUCCESS_GOTO(p
, rerror
, r
== 0, unlock_and_fail
);
362 pa_threaded_mainloop_unlock(p
->mainloop
);
366 pa_threaded_mainloop_unlock(p
->mainloop
);
370 static void success_cb(pa_stream
*s
, int success
, void *userdata
) {
371 pa_simple
*p
= userdata
;
376 p
->operation_success
= success
;
377 pa_threaded_mainloop_signal(p
->mainloop
, 0);
380 int pa_simple_drain(pa_simple
*p
, int *rerror
) {
381 pa_operation
*o
= NULL
;
385 CHECK_VALIDITY_RETURN_ANY(rerror
, p
->direction
== PA_STREAM_PLAYBACK
, PA_ERR_BADSTATE
, -1);
387 pa_threaded_mainloop_lock(p
->mainloop
);
388 CHECK_DEAD_GOTO(p
, rerror
, unlock_and_fail
);
390 o
= pa_stream_drain(p
->stream
, success_cb
, p
);
391 CHECK_SUCCESS_GOTO(p
, rerror
, o
, unlock_and_fail
);
393 p
->operation_success
= 0;
394 while (pa_operation_get_state(o
) == PA_OPERATION_RUNNING
) {
395 pa_threaded_mainloop_wait(p
->mainloop
);
396 CHECK_DEAD_GOTO(p
, rerror
, unlock_and_fail
);
398 CHECK_SUCCESS_GOTO(p
, rerror
, p
->operation_success
, unlock_and_fail
);
400 pa_operation_unref(o
);
401 pa_threaded_mainloop_unlock(p
->mainloop
);
408 pa_operation_cancel(o
);
409 pa_operation_unref(o
);
412 pa_threaded_mainloop_unlock(p
->mainloop
);
416 int pa_simple_flush(pa_simple
*p
, int *rerror
) {
417 pa_operation
*o
= NULL
;
421 CHECK_VALIDITY_RETURN_ANY(rerror
, p
->direction
== PA_STREAM_PLAYBACK
, PA_ERR_BADSTATE
, -1);
423 pa_threaded_mainloop_lock(p
->mainloop
);
424 CHECK_DEAD_GOTO(p
, rerror
, unlock_and_fail
);
426 o
= pa_stream_flush(p
->stream
, success_cb
, p
);
427 CHECK_SUCCESS_GOTO(p
, rerror
, o
, unlock_and_fail
);
429 p
->operation_success
= 0;
430 while (pa_operation_get_state(o
) == PA_OPERATION_RUNNING
) {
431 pa_threaded_mainloop_wait(p
->mainloop
);
432 CHECK_DEAD_GOTO(p
, rerror
, unlock_and_fail
);
434 CHECK_SUCCESS_GOTO(p
, rerror
, p
->operation_success
, unlock_and_fail
);
436 pa_operation_unref(o
);
437 pa_threaded_mainloop_unlock(p
->mainloop
);
444 pa_operation_cancel(o
);
445 pa_operation_unref(o
);
448 pa_threaded_mainloop_unlock(p
->mainloop
);
452 pa_usec_t
pa_simple_get_latency(pa_simple
*p
, int *rerror
) {
458 pa_threaded_mainloop_lock(p
->mainloop
);
461 CHECK_DEAD_GOTO(p
, rerror
, unlock_and_fail
);
463 if (pa_stream_get_latency(p
->stream
, &t
, &negative
) >= 0)
466 CHECK_SUCCESS_GOTO(p
, rerror
, pa_context_errno(p
->context
) == PA_ERR_NODATA
, unlock_and_fail
);
468 /* Wait until latency data is available again */
469 pa_threaded_mainloop_wait(p
->mainloop
);
472 pa_threaded_mainloop_unlock(p
->mainloop
);
474 return negative
? 0 : t
;
478 pa_threaded_mainloop_unlock(p
->mainloop
);
479 return (pa_usec_t
) -1;