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) \
55 if (!(expression)) { \
62 #define CHECK_SUCCESS_GOTO(p, rerror, expression, label) \
64 if (!(expression)) { \
66 *(rerror) = pa_context_errno((p)->context); \
71 #define CHECK_DEAD_GOTO(p, rerror, label) \
73 if (!(p)->context || pa_context_get_state((p)->context) != PA_CONTEXT_READY || \
74 !(p)->stream || pa_stream_get_state((p)->stream) != PA_STREAM_READY) { \
75 if (((p)->context && pa_context_get_state((p)->context) == PA_CONTEXT_FAILED) || \
76 ((p)->stream && pa_stream_get_state((p)->stream) == PA_STREAM_FAILED)) { \
78 *(rerror) = pa_context_errno((p)->context); \
81 *(rerror) = PA_ERR_BADSTATE; \
86 static void context_state_cb(pa_context
*c
, void *userdata
) {
87 pa_simple
*p
= userdata
;
91 switch (pa_context_get_state(c
)) {
92 case PA_CONTEXT_READY
:
93 case PA_CONTEXT_TERMINATED
:
94 case PA_CONTEXT_FAILED
:
95 pa_threaded_mainloop_signal(p
->mainloop
, 0);
98 case PA_CONTEXT_UNCONNECTED
:
99 case PA_CONTEXT_CONNECTING
:
100 case PA_CONTEXT_AUTHORIZING
:
101 case PA_CONTEXT_SETTING_NAME
:
106 static void stream_state_cb(pa_stream
*s
, void * userdata
) {
107 pa_simple
*p
= userdata
;
111 switch (pa_stream_get_state(s
)) {
113 case PA_STREAM_READY
:
114 case PA_STREAM_FAILED
:
115 case PA_STREAM_TERMINATED
:
116 pa_threaded_mainloop_signal(p
->mainloop
, 0);
119 case PA_STREAM_UNCONNECTED
:
120 case PA_STREAM_CREATING
:
125 static void stream_request_cb(pa_stream
*s
, size_t length
, void *userdata
) {
126 pa_simple
*p
= userdata
;
129 pa_threaded_mainloop_signal(p
->mainloop
, 0);
132 static void stream_latency_update_cb(pa_stream
*s
, void *userdata
) {
133 pa_simple
*p
= userdata
;
137 pa_threaded_mainloop_signal(p
->mainloop
, 0);
140 pa_simple
* pa_simple_new(
143 pa_stream_direction_t dir
,
145 const char *stream_name
,
146 const pa_sample_spec
*ss
,
147 const pa_channel_map
*map
,
148 const pa_buffer_attr
*attr
,
152 int error
= PA_ERR_INTERNAL
, r
;
154 CHECK_VALIDITY_RETURN_ANY(rerror
, !server
|| *server
, PA_ERR_INVALID
, NULL
);
155 CHECK_VALIDITY_RETURN_ANY(rerror
, dir
== PA_STREAM_PLAYBACK
|| dir
== PA_STREAM_RECORD
, PA_ERR_INVALID
, NULL
);
156 CHECK_VALIDITY_RETURN_ANY(rerror
, !dev
|| *dev
, PA_ERR_INVALID
, NULL
);
157 CHECK_VALIDITY_RETURN_ANY(rerror
, ss
&& pa_sample_spec_valid(ss
), PA_ERR_INVALID
, NULL
);
158 CHECK_VALIDITY_RETURN_ANY(rerror
, !map
|| (pa_channel_map_valid(map
) && map
->channels
== ss
->channels
), PA_ERR_INVALID
, NULL
)
160 p
= pa_xnew(pa_simple
, 1);
165 p
->read_index
= p
->read_length
= 0;
167 if (!(p
->mainloop
= pa_threaded_mainloop_new()))
170 if (!(p
->context
= pa_context_new(pa_threaded_mainloop_get_api(p
->mainloop
), name
)))
173 pa_context_set_state_callback(p
->context
, context_state_cb
, p
);
175 if (pa_context_connect(p
->context
, server
, 0, NULL
) < 0) {
176 error
= pa_context_errno(p
->context
);
180 pa_threaded_mainloop_lock(p
->mainloop
);
182 if (pa_threaded_mainloop_start(p
->mainloop
) < 0)
183 goto unlock_and_fail
;
185 /* Wait until the context is ready */
186 pa_threaded_mainloop_wait(p
->mainloop
);
188 if (pa_context_get_state(p
->context
) != PA_CONTEXT_READY
) {
189 error
= pa_context_errno(p
->context
);
190 goto unlock_and_fail
;
193 if (!(p
->stream
= pa_stream_new(p
->context
, stream_name
, ss
, map
))) {
194 error
= pa_context_errno(p
->context
);
195 goto unlock_and_fail
;
198 pa_stream_set_state_callback(p
->stream
, stream_state_cb
, p
);
199 pa_stream_set_read_callback(p
->stream
, stream_request_cb
, p
);
200 pa_stream_set_write_callback(p
->stream
, stream_request_cb
, p
);
201 pa_stream_set_latency_update_callback(p
->stream
, stream_latency_update_cb
, p
);
203 if (dir
== PA_STREAM_PLAYBACK
)
204 r
= pa_stream_connect_playback(p
->stream
, dev
, attr
,
205 PA_STREAM_INTERPOLATE_TIMING
206 |PA_STREAM_ADJUST_LATENCY
207 |PA_STREAM_AUTO_TIMING_UPDATE
, NULL
, NULL
);
209 r
= pa_stream_connect_record(p
->stream
, dev
, attr
,
210 PA_STREAM_INTERPOLATE_TIMING
211 |PA_STREAM_ADJUST_LATENCY
212 |PA_STREAM_AUTO_TIMING_UPDATE
);
215 error
= pa_context_errno(p
->context
);
216 goto unlock_and_fail
;
219 /* Wait until the stream is ready */
220 pa_threaded_mainloop_wait(p
->mainloop
);
222 /* Wait until the stream is ready */
223 if (pa_stream_get_state(p
->stream
) != PA_STREAM_READY
) {
224 error
= pa_context_errno(p
->context
);
225 goto unlock_and_fail
;
228 pa_threaded_mainloop_unlock(p
->mainloop
);
233 pa_threaded_mainloop_unlock(p
->mainloop
);
242 void pa_simple_free(pa_simple
*s
) {
246 pa_threaded_mainloop_stop(s
->mainloop
);
249 pa_stream_unref(s
->stream
);
252 pa_context_unref(s
->context
);
255 pa_threaded_mainloop_free(s
->mainloop
);
260 int pa_simple_write(pa_simple
*p
, const void*data
, size_t length
, int *rerror
) {
263 CHECK_VALIDITY_RETURN_ANY(rerror
, p
->direction
== PA_STREAM_PLAYBACK
, PA_ERR_BADSTATE
, -1);
264 CHECK_VALIDITY_RETURN_ANY(rerror
, data
&& length
, PA_ERR_INVALID
, -1);
266 pa_threaded_mainloop_lock(p
->mainloop
);
268 CHECK_DEAD_GOTO(p
, rerror
, unlock_and_fail
);
274 while (!(l
= pa_stream_writable_size(p
->stream
))) {
275 pa_threaded_mainloop_wait(p
->mainloop
);
276 CHECK_DEAD_GOTO(p
, rerror
, unlock_and_fail
);
279 CHECK_SUCCESS_GOTO(p
, rerror
, l
!= (size_t) -1, unlock_and_fail
);
284 r
= pa_stream_write(p
->stream
, data
, l
, NULL
, 0LL, PA_SEEK_RELATIVE
);
285 CHECK_SUCCESS_GOTO(p
, rerror
, r
>= 0, unlock_and_fail
);
287 data
= (const uint8_t*) data
+ l
;
291 pa_threaded_mainloop_unlock(p
->mainloop
);
295 pa_threaded_mainloop_unlock(p
->mainloop
);
299 int pa_simple_read(pa_simple
*p
, void*data
, size_t length
, int *rerror
) {
302 CHECK_VALIDITY_RETURN_ANY(rerror
, p
->direction
== PA_STREAM_RECORD
, PA_ERR_BADSTATE
, -1);
303 CHECK_VALIDITY_RETURN_ANY(rerror
, data
&& length
, PA_ERR_INVALID
, -1);
305 pa_threaded_mainloop_lock(p
->mainloop
);
307 CHECK_DEAD_GOTO(p
, rerror
, unlock_and_fail
);
312 while (!p
->read_data
) {
315 r
= pa_stream_peek(p
->stream
, &p
->read_data
, &p
->read_length
);
316 CHECK_SUCCESS_GOTO(p
, rerror
, r
== 0, unlock_and_fail
);
319 pa_threaded_mainloop_wait(p
->mainloop
);
320 CHECK_DEAD_GOTO(p
, rerror
, unlock_and_fail
);
325 l
= p
->read_length
< length
? p
->read_length
: length
;
326 memcpy(data
, (const uint8_t*) p
->read_data
+p
->read_index
, l
);
328 data
= (uint8_t*) data
+ l
;
334 if (!p
->read_length
) {
337 r
= pa_stream_drop(p
->stream
);
342 CHECK_SUCCESS_GOTO(p
, rerror
, r
== 0, unlock_and_fail
);
346 pa_threaded_mainloop_unlock(p
->mainloop
);
350 pa_threaded_mainloop_unlock(p
->mainloop
);
354 static void success_cb(pa_stream
*s
, int success
, void *userdata
) {
355 pa_simple
*p
= userdata
;
360 p
->operation_success
= success
;
361 pa_threaded_mainloop_signal(p
->mainloop
, 0);
364 int pa_simple_drain(pa_simple
*p
, int *rerror
) {
365 pa_operation
*o
= NULL
;
369 CHECK_VALIDITY_RETURN_ANY(rerror
, p
->direction
== PA_STREAM_PLAYBACK
, PA_ERR_BADSTATE
, -1);
371 pa_threaded_mainloop_lock(p
->mainloop
);
372 CHECK_DEAD_GOTO(p
, rerror
, unlock_and_fail
);
374 o
= pa_stream_drain(p
->stream
, success_cb
, p
);
375 CHECK_SUCCESS_GOTO(p
, rerror
, o
, unlock_and_fail
);
377 p
->operation_success
= 0;
378 while (pa_operation_get_state(o
) != PA_OPERATION_DONE
) {
379 pa_threaded_mainloop_wait(p
->mainloop
);
380 CHECK_DEAD_GOTO(p
, rerror
, unlock_and_fail
);
382 CHECK_SUCCESS_GOTO(p
, rerror
, p
->operation_success
, unlock_and_fail
);
384 pa_operation_unref(o
);
385 pa_threaded_mainloop_unlock(p
->mainloop
);
392 pa_operation_cancel(o
);
393 pa_operation_unref(o
);
396 pa_threaded_mainloop_unlock(p
->mainloop
);
400 int pa_simple_flush(pa_simple
*p
, int *rerror
) {
401 pa_operation
*o
= NULL
;
405 CHECK_VALIDITY_RETURN_ANY(rerror
, p
->direction
== PA_STREAM_PLAYBACK
, PA_ERR_BADSTATE
, -1);
407 pa_threaded_mainloop_lock(p
->mainloop
);
408 CHECK_DEAD_GOTO(p
, rerror
, unlock_and_fail
);
410 o
= pa_stream_flush(p
->stream
, success_cb
, p
);
411 CHECK_SUCCESS_GOTO(p
, rerror
, o
, unlock_and_fail
);
413 p
->operation_success
= 0;
414 while (pa_operation_get_state(o
) != PA_OPERATION_DONE
) {
415 pa_threaded_mainloop_wait(p
->mainloop
);
416 CHECK_DEAD_GOTO(p
, rerror
, unlock_and_fail
);
418 CHECK_SUCCESS_GOTO(p
, rerror
, p
->operation_success
, unlock_and_fail
);
420 pa_operation_unref(o
);
421 pa_threaded_mainloop_unlock(p
->mainloop
);
428 pa_operation_cancel(o
);
429 pa_operation_unref(o
);
432 pa_threaded_mainloop_unlock(p
->mainloop
);
436 pa_usec_t
pa_simple_get_latency(pa_simple
*p
, int *rerror
) {
442 pa_threaded_mainloop_lock(p
->mainloop
);
445 CHECK_DEAD_GOTO(p
, rerror
, unlock_and_fail
);
447 if (pa_stream_get_latency(p
->stream
, &t
, &negative
) >= 0)
450 CHECK_SUCCESS_GOTO(p
, rerror
, pa_context_errno(p
->context
) == PA_ERR_NODATA
, unlock_and_fail
);
452 /* Wait until latency data is available again */
453 pa_threaded_mainloop_wait(p
->mainloop
);
456 pa_threaded_mainloop_unlock(p
->mainloop
);
458 return negative
? 0 : t
;
462 pa_threaded_mainloop_unlock(p
->mainloop
);
463 return (pa_usec_t
) -1;