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_IS_GOOD(pa_context_get_state((p)->context)) || \
74 !(p)->stream || !PA_STREAM_IS_GOOD(pa_stream_get_state((p)->stream))) { \
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_xnew0(pa_simple, 1);
163 if (!(p->mainloop = pa_threaded_mainloop_new()))
166 if (!(p->context = pa_context_new(pa_threaded_mainloop_get_api(p->mainloop), name)))
169 pa_context_set_state_callback(p->context, context_state_cb, p);
171 if (pa_context_connect(p->context, server, 0, NULL) < 0) {
172 error = pa_context_errno(p->context);
176 pa_threaded_mainloop_lock(p->mainloop);
178 if (pa_threaded_mainloop_start(p->mainloop) < 0)
179 goto unlock_and_fail;
181 /* Wait until the context is ready */
182 pa_threaded_mainloop_wait(p->mainloop);
184 if (pa_context_get_state(p->context) != PA_CONTEXT_READY) {
185 error = pa_context_errno(p->context);
186 goto unlock_and_fail;
189 if (!(p->stream = pa_stream_new(p->context, stream_name, ss, map))) {
190 error = pa_context_errno(p->context);
191 goto unlock_and_fail;
194 pa_stream_set_state_callback(p->stream, stream_state_cb, p);
195 pa_stream_set_read_callback(p->stream, stream_request_cb, p);
196 pa_stream_set_write_callback(p->stream, stream_request_cb, p);
197 pa_stream_set_latency_update_callback(p->stream, stream_latency_update_cb, p);
199 if (dir == PA_STREAM_PLAYBACK)
200 r = pa_stream_connect_playback(p->stream, dev, attr,
201 PA_STREAM_INTERPOLATE_TIMING
202 |PA_STREAM_ADJUST_LATENCY
203 |PA_STREAM_AUTO_TIMING_UPDATE, NULL, NULL);
205 r = pa_stream_connect_record(p->stream, dev, attr,
206 PA_STREAM_INTERPOLATE_TIMING
207 |PA_STREAM_ADJUST_LATENCY
208 |PA_STREAM_AUTO_TIMING_UPDATE);
211 error = pa_context_errno(p->context);
212 goto unlock_and_fail;
215 /* Wait until the stream is ready */
216 pa_threaded_mainloop_wait(p->mainloop);
218 /* Wait until the stream is ready */
219 if (pa_stream_get_state(p->stream) != PA_STREAM_READY) {
220 error = pa_context_errno(p->context);
221 goto unlock_and_fail;
224 pa_threaded_mainloop_unlock(p->mainloop);
229 pa_threaded_mainloop_unlock(p->mainloop);
238 void pa_simple_free(pa_simple *s) {
242 pa_threaded_mainloop_stop(s->mainloop);
245 pa_stream_unref(s->stream);
248 pa_context_unref(s->context);
251 pa_threaded_mainloop_free(s->mainloop);
256 int pa_simple_write(pa_simple *p, const void*data, size_t length, int *rerror) {
259 CHECK_VALIDITY_RETURN_ANY(rerror, p->direction == PA_STREAM_PLAYBACK, PA_ERR_BADSTATE, -1);
260 CHECK_VALIDITY_RETURN_ANY(rerror, data && length, PA_ERR_INVALID, -1);
262 pa_threaded_mainloop_lock(p->mainloop);
264 CHECK_DEAD_GOTO(p, rerror, unlock_and_fail);
270 while (!(l = pa_stream_writable_size(p->stream))) {
271 pa_threaded_mainloop_wait(p->mainloop);
272 CHECK_DEAD_GOTO(p, rerror, unlock_and_fail);
275 CHECK_SUCCESS_GOTO(p, rerror, l != (size_t) -1, unlock_and_fail);
280 r = pa_stream_write(p->stream, data, l, NULL, 0LL, PA_SEEK_RELATIVE);
281 CHECK_SUCCESS_GOTO(p, rerror, r >= 0, unlock_and_fail);
283 data = (const uint8_t*) data + l;
287 pa_threaded_mainloop_unlock(p->mainloop);
291 pa_threaded_mainloop_unlock(p->mainloop);
295 int pa_simple_read(pa_simple *p, void*data, size_t length, int *rerror) {
298 CHECK_VALIDITY_RETURN_ANY(rerror, p->direction == PA_STREAM_RECORD, PA_ERR_BADSTATE, -1);
299 CHECK_VALIDITY_RETURN_ANY(rerror, data && length, PA_ERR_INVALID, -1);
301 pa_threaded_mainloop_lock(p->mainloop);
303 CHECK_DEAD_GOTO(p, rerror, unlock_and_fail);
308 while (!p->read_data) {
311 r = pa_stream_peek(p->stream, &p->read_data, &p->read_length);
312 CHECK_SUCCESS_GOTO(p, rerror, r == 0, unlock_and_fail);
315 pa_threaded_mainloop_wait(p->mainloop);
316 CHECK_DEAD_GOTO(p, rerror, unlock_and_fail);
321 l = p->read_length < length ? p->read_length : length;
322 memcpy(data, (const uint8_t*) p->read_data+p->read_index, l);
324 data = (uint8_t*) data + l;
330 if (!p->read_length) {
333 r = pa_stream_drop(p->stream);
338 CHECK_SUCCESS_GOTO(p, rerror, r == 0, unlock_and_fail);
342 pa_threaded_mainloop_unlock(p->mainloop);
346 pa_threaded_mainloop_unlock(p->mainloop);
350 static void success_cb(pa_stream *s, int success, void *userdata) {
351 pa_simple *p = userdata;
356 p->operation_success = success;
357 pa_threaded_mainloop_signal(p->mainloop, 0);
360 int pa_simple_drain(pa_simple *p, int *rerror) {
361 pa_operation *o = NULL;
365 CHECK_VALIDITY_RETURN_ANY(rerror, p->direction == PA_STREAM_PLAYBACK, PA_ERR_BADSTATE, -1);
367 pa_threaded_mainloop_lock(p->mainloop);
368 CHECK_DEAD_GOTO(p, rerror, unlock_and_fail);
370 o = pa_stream_drain(p->stream, success_cb, p);
371 CHECK_SUCCESS_GOTO(p, rerror, o, unlock_and_fail);
373 p->operation_success = 0;
374 while (pa_operation_get_state(o) != PA_OPERATION_DONE) {
375 pa_threaded_mainloop_wait(p->mainloop);
376 CHECK_DEAD_GOTO(p, rerror, unlock_and_fail);
378 CHECK_SUCCESS_GOTO(p, rerror, p->operation_success, unlock_and_fail);
380 pa_operation_unref(o);
381 pa_threaded_mainloop_unlock(p->mainloop);
388 pa_operation_cancel(o);
389 pa_operation_unref(o);
392 pa_threaded_mainloop_unlock(p->mainloop);
396 int pa_simple_flush(pa_simple *p, int *rerror) {
397 pa_operation *o = NULL;
401 CHECK_VALIDITY_RETURN_ANY(rerror, p->direction == PA_STREAM_PLAYBACK, PA_ERR_BADSTATE, -1);
403 pa_threaded_mainloop_lock(p->mainloop);
404 CHECK_DEAD_GOTO(p, rerror, unlock_and_fail);
406 o = pa_stream_flush(p->stream, success_cb, p);
407 CHECK_SUCCESS_GOTO(p, rerror, o, unlock_and_fail);
409 p->operation_success = 0;
410 while (pa_operation_get_state(o) != PA_OPERATION_DONE) {
411 pa_threaded_mainloop_wait(p->mainloop);
412 CHECK_DEAD_GOTO(p, rerror, unlock_and_fail);
414 CHECK_SUCCESS_GOTO(p, rerror, p->operation_success, unlock_and_fail);
416 pa_operation_unref(o);
417 pa_threaded_mainloop_unlock(p->mainloop);
424 pa_operation_cancel(o);
425 pa_operation_unref(o);
428 pa_threaded_mainloop_unlock(p->mainloop);
432 pa_usec_t pa_simple_get_latency(pa_simple *p, int *rerror) {
438 pa_threaded_mainloop_lock(p->mainloop);
441 CHECK_DEAD_GOTO(p, rerror, unlock_and_fail);
443 if (pa_stream_get_latency(p->stream, &t, &negative) >= 0)
446 CHECK_SUCCESS_GOTO(p, rerror, pa_context_errno(p->context) == PA_ERR_NODATA, unlock_and_fail);
448 /* Wait until latency data is available again */
449 pa_threaded_mainloop_wait(p->mainloop);
452 pa_threaded_mainloop_unlock(p->mainloop);
454 return negative ? 0 : t;
458 pa_threaded_mainloop_unlock(p->mainloop);
459 return (pa_usec_t) -1;