7 #include "polyp-error.h"
10 struct pa_mainloop *mainloop;
11 struct pa_context *context;
12 struct pa_stream *stream;
17 static int iterate(struct pa_simple *p, int block, int *perror) {
18 assert(p && p->context && p->mainloop);
20 if (!block && !pa_context_is_pending(p->context))
24 if (pa_context_is_dead(p->context) || (p->stream && pa_stream_is_dead(p->stream))) {
26 *perror = pa_context_errno(p->context);
30 if (pa_mainloop_iterate(p->mainloop, 1, NULL) < 0) {
32 *perror = PA_ERROR_INTERNAL;
35 } while (pa_context_is_pending(p->context));
40 struct pa_simple* pa_simple_new(
43 enum pa_stream_direction dir,
45 const char *stream_name,
46 const struct pa_sample_spec *ss,
47 const struct pa_buffer_attr *attr,
51 int error = PA_ERROR_INTERNAL;
54 p = malloc(sizeof(struct pa_simple));
58 p->mainloop = pa_mainloop_new();
62 if (!(p->context = pa_context_new(pa_mainloop_get_api(p->mainloop), name)))
65 if (pa_context_connect(p->context, server, NULL, NULL) < 0) {
66 error = pa_context_errno(p->context);
70 /* Wait until the context is ready */
71 while (!pa_context_is_ready(p->context)) {
72 if (iterate(p, 1, &error) < 0)
76 if (!(p->stream = pa_stream_new(p->context, dir, dev, stream_name, ss, attr, NULL, NULL)))
79 /* Wait until the stream is ready */
80 while (!pa_stream_is_ready(p->stream)) {
81 if (iterate(p, 1, &error) < 0)
94 void pa_simple_free(struct pa_simple *s) {
98 pa_stream_free(s->stream);
101 pa_context_free(s->context);
104 pa_mainloop_free(s->mainloop);
109 int pa_simple_write(struct pa_simple *p, const void*data, size_t length, int *perror) {
115 while (!(l = pa_stream_writable_size(p->stream)))
116 if (iterate(p, 1, perror) < 0)
122 pa_stream_write(p->stream, data, l);
127 /* Make sure that no data is pending for write */
128 if (iterate(p, 0, perror) < 0)
134 int pa_simple_read(struct pa_simple *s, void*data, size_t length, int *perror) {
139 static void drain_complete(struct pa_stream *s, void *userdata) {
140 struct pa_simple *p = userdata;
145 int pa_simple_drain(struct pa_simple *p, int *perror) {
148 pa_stream_drain(p->stream, drain_complete, p);
150 while (!p->drained) {
151 if (iterate(p, 1, perror) < 0) {
152 pa_stream_drain(p->stream, NULL, NULL);