diff options
Diffstat (limited to 'src/plugin.c')
-rw-r--r-- | src/plugin.c | 148 |
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, ¤t_request->ss); + stream = pa_stream_new(c, "xmms", ¤t_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) { |