summaryrefslogtreecommitdiffstats
path: root/src/plugin.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugin.c')
-rw-r--r--src/plugin.c148
1 files changed, 94 insertions, 54 deletions
diff --git a/src/plugin.c b/src/plugin.c
index 4f9b515..640540d 100644
--- a/src/plugin.c
+++ b/src/plugin.c
@@ -1,6 +1,13 @@
+#include <stdio.h>
+#include <assert.h>
#include <pthread.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <plugin.h>
#include <polyp/mainloop.h>
+#include <polyp/polyplib.h>
static pthread_cond_t request_cond = PTHREAD_COND_INITIALIZER;
static pthread_mutex_t request_mutex = PTHREAD_MUTEX_INITIALIZER;
@@ -16,7 +23,9 @@ struct request {
MESSAGE_LATENCY,
MESSAGE_WRITABLE,
MESSAGE_TRIGGER,
- } type;
+ MESSAGE_GETVOLUME,
+ MESSAGE_SETVOLUME
+ } message;
void *data;
struct pa_sample_spec ss;
size_t length;
@@ -37,11 +46,17 @@ static struct pa_mainloop_api *mainloop_api = NULL;
static int failed = 0;
static pa_volume_t volume = PA_VOLUME_NORM;
static size_t written = 0;
-static pa_usec_t latency;
static int do_trigger;
+static struct pa_sample_spec sample_spec;
+
+static void *memdup(void *p, size_t l) {
+ void *r = malloc(l);
+ memcpy(r, p, l);
+ return r;
+}
static void finish_request(int success) {
- failed = 1;
+ failed = success;
pthread_mutex_lock(&request_mutex);
@@ -69,18 +84,18 @@ static void subscribe_callback(struct pa_context *c, enum pa_subscription_event_
if (!stream || index != pa_stream_get_index(stream) || t != (PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE))
return;
- pa_operation_unref(pa_context_get_sink_input_info(c, index, info_callback, NULL);
+ pa_operation_unref(pa_context_get_sink_input_info(c, index, info_callback, NULL));
}
static void stream_state_callback(struct pa_stream *s, void *userdata) {
assert(stream == s);
- switch(pa_stream_get_state(c)) {
+ switch(pa_stream_get_state(s)) {
case PA_STREAM_CREATING:
break;
case PA_STREAM_READY:
- assert(current_request && current_request->type == MESSAGE_OPEN);
- pa_operation_unref(pa_context_get_sink_input_info(context, pa_stream_get_index(s), info_callback, NULL);
+ assert(current_request && current_request->message == MESSAGE_OPEN);
+ pa_operation_unref(pa_context_get_sink_input_info(context, pa_stream_get_index(s), info_callback, NULL));
finish_request(1);
break;
default:
@@ -100,12 +115,12 @@ static void context_state_callback(struct pa_context *c, void *userdata) {
case PA_CONTEXT_READY :
assert(!stream && current_request);
pa_context_set_subscribe_callback(context, subscribe_callback, NULL);
- pa_operation_unref(pa_context_subscribe(context, PA_SUBSCRIPTION_MASK_SINK_INPUT, NULL, NULL);
+ pa_operation_unref(pa_context_subscribe(context, PA_SUBSCRIPTION_MASK_SINK_INPUT, NULL, NULL));
- stream = pa_stream_new(c, &current_request->ss);
+ stream = pa_stream_new(c, "xmms", &current_request->ss);
assert(stream);
- pa_stream_set_state(stream, stream_state_callback);
+ pa_stream_set_state_callback(stream, stream_state_callback, NULL);
pa_stream_connect_playback(stream, NULL, NULL);
break;
@@ -131,13 +146,16 @@ static void context_success_callback(struct pa_context *c, int success, void *us
static void latency_callback(struct pa_stream *s, pa_usec_t latency, void *userdata) {
assert(s == stream && s);
- assert(current_request && current_request>type == MESSAGE_LATENCY);
+ assert(current_request && current_request->message == MESSAGE_LATENCY);
current_request->value = latency;
finish_request(latency != (pa_usec_t) -1);
}
-static void request_func(struct pa_mainloop*api, struct pa_io_event *io, enum pa_io_event_flags f, void *userdata) {
+static void request_func(struct pa_mainloop_api*api, struct pa_io_event *io, int fd, enum pa_io_event_flags f, void *userdata) {
char x;
+
+ fprintf(stderr, "REQUEST\n");
+
assert(api && io && f == PA_IO_EVENT_INPUT);
@@ -147,9 +165,9 @@ static void request_func(struct pa_mainloop*api, struct pa_io_event *io, enum pa
if (current_request) {
if (failed) {
- fail();
+ finish_request(0);
} else {
- switch (current_request->type) {
+ switch (current_request->message) {
case MESSAGE_OPEN:
assert(!context && !stream);
context = pa_context_new(api, "xmms");
@@ -183,7 +201,7 @@ static void request_func(struct pa_mainloop*api, struct pa_io_event *io, enum pa
case MESSAGE_PAUSE:
case MESSAGE_UNPAUSE:
assert(context && stream);
- pa_operation_unref(pa_stream_cork(stream, current_request->type == MESSAGE_UNPAUSE, stream_success_callback, NULL));
+ pa_operation_unref(pa_stream_cork(stream, current_request->message == MESSAGE_UNPAUSE, stream_success_callback, NULL));
break;
case MESSAGE_LATENCY:
@@ -238,7 +256,7 @@ static void* thread_func(void *t) {
pa_mainloop_run(m, NULL);
- api->io_free(io);
+ mainloop_api->io_free(io);
pa_mainloop_free(m);
mainloop_api = NULL;
@@ -260,7 +278,6 @@ static void start_thread(void) {
}
static void stop_thread(void) {
- struct request req;
assert(thread_running);
pthread_join(thread_id, NULL);
@@ -273,26 +290,6 @@ static void stop_thread(void) {
pipe_fds[0] = pipe_fds[1] = -1;
}
-static void polyp_get_volume(int *l, int *r) {
- struct request r;
- int v;
-
- r.message = MESSAGE_GET_VOLUME;
- request_execute(&r);
-
- v = (r.volume*100)/PA_VOLUME_NORM;
-
- *r = *l = v > 100 ? 100 : v;
-}
-
-void polyp_set_volume(int l, int r) {
- struct request r;
-
- r.message = MESSAGE_SET_VOLUME;
- r.volume = ((l+r)*PA_VOLUME_NORM)/200;
- request_execute(&r);
-}
-
static void request_execute(struct request *r) {
char x = 'x';
assert(r);
@@ -314,9 +311,34 @@ static void request_execute(struct request *r) {
pthread_mutex_unlock(&request_mutex);
}
+static void polyp_get_volume(int *l, int *r) {
+ struct request req;
+ int v;
+ fprintf(stderr, "get_volume\n");
+
+ req.message = MESSAGE_GETVOLUME;
+ request_execute(&req);
+
+ v = (req.volume*100)/PA_VOLUME_NORM;
+
+ *r = *l = v > 100 ? 100 : v;
+}
+
+void polyp_set_volume(int l, int r) {
+ struct request req;
+ fprintf(stderr, "set_volume\n");
+
+ req.message = MESSAGE_SETVOLUME;
+ req.volume = ((l+r)*PA_VOLUME_NORM)/200;
+ request_execute(&req);
+}
+
+
static void polyp_pause(short b) {
struct request r;
-
+
+ fprintf(stderr, "pause: %s\n", b ? "yes" : "no");
+
r.message = b ? MESSAGE_PAUSE : MESSAGE_UNPAUSE;
request_execute(&r);
}
@@ -324,6 +346,9 @@ static void polyp_pause(short b) {
static int polyp_free(void) {
int ret;
struct request r;
+
+ fprintf(stderr, "free\n");
+
r.message = MESSAGE_WRITABLE;
request_execute(&r);
@@ -340,6 +365,9 @@ static int polyp_free(void) {
static int polyp_playing(void) {
struct request r;
+
+ fprintf(stderr, "playing\n");
+
r.message = MESSAGE_LATENCY;
request_execute(&r);
@@ -347,12 +375,16 @@ static int polyp_playing(void) {
}
static int polyp_get_written_time(void) {
+ fprintf(stderr, "get_written_time\n");
+
return ((written/pa_frame_size(&sample_spec))*1000)/sample_spec.rate;
}
static int polyp_get_output_time(void) {
int t, ms;
struct request r;
+ fprintf(stderr, "get_output_time\n");
+
r.message = MESSAGE_LATENCY;
request_execute(&r);
@@ -367,6 +399,8 @@ static int polyp_get_output_time(void) {
static void polyp_flush(int time) {
struct request r;
+ fprintf(stderr, "flush\n");
+
r.message = MESSAGE_FLUSH;
request_execute(&r);
@@ -375,8 +409,10 @@ static void polyp_flush(int time) {
static void polyp_write(void* ptr, int length) {
struct request r;
+ fprintf(stderr, "write\n");
+
r.message = MESSAGE_WRITE;
- r.data = ptr;
+ r.data = memdup(ptr, length);
r.length = length;
request_execute(&r);
@@ -387,14 +423,15 @@ static void polyp_write(void* ptr, int length) {
static int polyp_open(AFormat fmt, int rate, int nch) {
struct request r;
+ fprintf(stderr, "open\n");
if (fmt == FMT_U8)
r.ss.format = PA_SAMPLE_U8;
else if (fmt == FMT_S16_LE)
r.ss.format = PA_SAMPLE_S16LE;
- else if (fmt == FM_S16_BE)
+ else if (fmt == FMT_S16_BE)
r.ss.format = PA_SAMPLE_S16BE;
- else if (fmt == FM_S16_NE)
+ else if (fmt == FMT_S16_NE)
r.ss.format = PA_SAMPLE_S16NE;
else
return 0;
@@ -405,23 +442,26 @@ static int polyp_open(AFormat fmt, int rate, int nch) {
if (!pa_sample_spec_valid(&r.ss))
return 0;
+ sample_spec = r.ss;
+
start_thread();
r.message = MESSAGE_OPEN;
request_execute(&r);
- if (!r->success) {
+ if (!r.success) {
stop_thread();
return 0;
}
- written = do_trigger = 0;
+ written = do_trigger = failed = 0;
return 1;
}
static void polyp_close(void) {
struct request r;
+ fprintf(stderr, "close\n");
assert(thread_running);
@@ -433,27 +473,27 @@ static void polyp_close(void) {
static void polyp_init(void) {
+ fprintf(stderr, "init\n");
}
static OutputPlugin polyp_plugin = {
NULL,
NULL,
"Polypaudio Output Plugin", /* Description */
- polyp_init, /* done */
+ polyp_init,
NULL, /* polyp_about, */
NULL, /* polyp_configure, */
polyp_get_volume,
polyp_set_volume,
-
- polyp_open, /* done */
- polyp_write, /* done */
- polyp_close, /* done */
- polyp_flush, /* done */
- polyp_pause, /* done */
- polyp_free, /* done */
- polyp_playing, /* done */
- polyp_get_output_time, /* done */
- polyp_get_written_time, /* done */
+ polyp_open,
+ polyp_write,
+ polyp_close,
+ polyp_flush,
+ polyp_pause,
+ polyp_free,
+ polyp_playing,
+ polyp_get_output_time,
+ polyp_get_written_time,
};
OutputPlugin *get_oplugin_info(void) {