summaryrefslogtreecommitdiffstats
path: root/pulse/pulse.c
diff options
context:
space:
mode:
authorPierre Ossman <ossman@cendio.se>2006-07-12 16:47:20 +0200
committerTakashi Iwai <tiwai@suse.de>2006-07-12 16:47:20 +0200
commit9304087e46a38f932959598720d1e048a6e1042a (patch)
tree627fc036583567f41c747d0b4bef06f847d408d1 /pulse/pulse.c
parent65028b0c19c6aa3ba469cbb9d52c56655d3b67b5 (diff)
Follow Polypaudio/PulseAudio name change
Polypaudio recently changed its name to PulseAudio which affects the names of libraries of header files. Update the polyp, now pulse, plug-in to follow this name change. Signed-off-by: Pierre Ossman <ossman@cendio.se>
Diffstat (limited to 'pulse/pulse.c')
-rw-r--r--pulse/pulse.c260
1 files changed, 260 insertions, 0 deletions
diff --git a/pulse/pulse.c b/pulse/pulse.c
new file mode 100644
index 0000000..fd80d9c
--- /dev/null
+++ b/pulse/pulse.c
@@ -0,0 +1,260 @@
+/*
+ * ALSA <-> PulseAudio plugins
+ *
+ * Copyright (c) 2006 by Pierre Ossman <ossman@cendio.se>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <signal.h>
+#include <sys/poll.h>
+
+#include "pulse.h"
+
+int pulse_check_connection(snd_pulse_t *p)
+{
+ pa_context_state_t state;
+
+ assert(p && p->context && p->mainloop);
+
+ state = pa_context_get_state(p->context);
+
+ if (state != PA_CONTEXT_READY)
+ return -EIO;
+
+ return 0;
+}
+
+void pulse_stream_state_cb(pa_stream *s, void * userdata)
+{
+ snd_pulse_t *p = userdata;
+
+ assert(s);
+ assert(p);
+
+ pa_threaded_mainloop_signal(p->mainloop, 0);
+}
+
+void pulse_stream_success_cb(pa_stream *s, int success, void *userdata)
+{
+ snd_pulse_t *p = userdata;
+
+ assert(s);
+ assert(p);
+
+ pa_threaded_mainloop_signal(p->mainloop, 0);
+}
+
+void pulse_context_success_cb(pa_context *c, int success, void *userdata)
+{
+ snd_pulse_t *p = userdata;
+
+ assert(c);
+ assert(p);
+
+ pa_threaded_mainloop_signal(p->mainloop, 0);
+}
+
+int pulse_wait_operation(snd_pulse_t *p, pa_operation *o)
+{
+ assert(p && o && (p->state == PULSE_STATE_READY) && p->mainloop);
+
+ while (pa_operation_get_state(o) == PA_OPERATION_RUNNING)
+ pa_threaded_mainloop_wait(p->mainloop);
+
+ return 0;
+}
+
+int pulse_wait_stream_state(snd_pulse_t *p, pa_stream *stream, pa_stream_state_t target)
+{
+ pa_stream_state_t state;
+
+ assert(p && stream && (p->state == PULSE_STATE_READY) && p->mainloop);
+
+ while (1) {
+ state = pa_stream_get_state(stream);
+
+ if (state == PA_STREAM_FAILED)
+ return -EIO;
+
+ if (state == target)
+ break;
+
+ pa_threaded_mainloop_wait(p->mainloop);
+ }
+
+ return 0;
+}
+
+static void context_state_cb(pa_context *c, void *userdata) {
+ snd_pulse_t *p = userdata;
+ assert(c);
+
+ switch (pa_context_get_state(c)) {
+ case PA_CONTEXT_READY:
+ case PA_CONTEXT_TERMINATED:
+ case PA_CONTEXT_FAILED:
+ pa_threaded_mainloop_signal(p->mainloop, 0);
+ break;
+
+ case PA_CONTEXT_UNCONNECTED:
+ case PA_CONTEXT_CONNECTING:
+ case PA_CONTEXT_AUTHORIZING:
+ case PA_CONTEXT_SETTING_NAME:
+ break;
+ }
+}
+
+snd_pulse_t *pulse_new()
+{
+ snd_pulse_t *p;
+ int fd[2] = { -1, -1 };
+ char proc[PATH_MAX], buf[PATH_MAX + 20];
+
+ p = calloc(1, sizeof(snd_pulse_t));
+ assert(p);
+
+ p->state = PULSE_STATE_INIT;
+
+ if (pipe(fd)) {
+ free(p);
+ return NULL;
+ }
+
+ p->main_fd = fd[0];
+ p->thread_fd = fd[1];
+
+ fcntl(fd[0], F_SETFL, O_NONBLOCK);
+ fcntl(fd[1], F_SETFL, O_NONBLOCK);
+
+ signal(SIGPIPE, SIG_IGN); /* Yes, ugly as hell */
+
+ p->mainloop = pa_threaded_mainloop_new();
+ assert(p->mainloop);
+
+ if (pa_threaded_mainloop_start(p->mainloop) < 0) {
+ pa_threaded_mainloop_free(p->mainloop);
+ close(fd[0]);
+ close(fd[1]);
+ free(p);
+ return NULL;
+ }
+
+ if (pa_get_binary_name(proc, sizeof(proc)))
+ snprintf(buf, sizeof(buf), "ALSA plug-in [%s]", pa_path_get_filename(proc));
+ else
+ snprintf(buf, sizeof(buf), "ALSA plug-in");
+
+ p->context = pa_context_new(pa_threaded_mainloop_get_api(p->mainloop), buf);
+ assert(p->context);
+
+ return p;
+}
+
+void pulse_free(snd_pulse_t *p)
+{
+ pa_threaded_mainloop_stop(p->mainloop);
+
+ pa_context_unref(p->context);
+ pa_threaded_mainloop_free(p->mainloop);
+
+ close(p->thread_fd);
+ close(p->main_fd);
+
+ free(p);
+}
+
+int pulse_connect(snd_pulse_t *p, const char *server)
+{
+ int err;
+
+ assert(p && p->context && p->mainloop && (p->state == PULSE_STATE_INIT));
+
+ pa_threaded_mainloop_lock(p->mainloop);
+
+ err = pa_context_connect(p->context, server, 0, NULL);
+ if (err < 0)
+ goto error;
+
+ pa_context_set_state_callback(p->context, context_state_cb, p);
+
+ pa_threaded_mainloop_wait(p->mainloop);
+
+ if (pa_context_get_state(p->context) != PA_CONTEXT_READY)
+ goto error;
+
+ pa_threaded_mainloop_unlock(p->mainloop);
+
+ p->state = PULSE_STATE_READY;
+
+ return 0;
+
+error:
+ fprintf(stderr, "*** PULSEAUDIO: Unable to connect: %s\n",
+ pa_strerror(pa_context_errno(p->context)));
+
+ pa_threaded_mainloop_unlock(p->mainloop);
+
+ return -ECONNREFUSED;
+}
+
+void pulse_poll_activate(snd_pulse_t *p)
+{
+ assert(p);
+
+ write(p->thread_fd, "a", 1);
+}
+
+void pulse_poll_deactivate(snd_pulse_t *p)
+{
+ char buf[10];
+
+ assert(p);
+
+ /* Drain the pipe */
+ while (read(p->main_fd, buf, sizeof(buf)) > 0);
+}
+
+int pulse_poll_descriptors_count(snd_pulse_t *p)
+{
+ assert(p);
+
+ if (p->main_fd >= 0)
+ return 1;
+ else
+ return 0;
+}
+
+int pulse_poll_descriptors(snd_pulse_t *p, struct pollfd *pfd, unsigned int space)
+{
+ assert(p);
+
+ assert(space >= 1);
+
+ pfd[0].fd = p->main_fd;
+ pfd[0].events = POLLIN;
+ pfd[0].revents = 0;
+
+ return 1;
+}
+
+int pulse_poll_revents(snd_pulse_t *p, struct pollfd *pfd, unsigned int nfds, unsigned short *revents)
+{
+ assert(p);
+
+ return 1;
+}