diff options
author | Lennart Poettering <lennart@poettering.net> | 2004-08-26 15:32:51 +0000 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2004-08-26 15:32:51 +0000 |
commit | f855ed495e161b83f939552d00ba9bd2a95978ff (patch) | |
tree | 70eb133c61e4e3aa5a9a8feefbbe2acc0a07ef74 /src/thread.c | |
parent | 2c4f7a21f22cdc3952edca71e60797be9955d139 (diff) |
rename some stuff
git-svn-id: file:///home/lennart/svn/public/xmms-pulse/trunk@6 ef929aba-56e2-0310-84e0-b7573d389508
Diffstat (limited to 'src/thread.c')
-rw-r--r-- | src/thread.c | 461 |
1 files changed, 0 insertions, 461 deletions
diff --git a/src/thread.c b/src/thread.c deleted file mode 100644 index 4f9b515..0000000 --- a/src/thread.c +++ /dev/null @@ -1,461 +0,0 @@ -#include <pthread.h> - -#include <polyp/mainloop.h> - -static pthread_cond_t request_cond = PTHREAD_COND_INITIALIZER; -static pthread_mutex_t request_mutex = PTHREAD_MUTEX_INITIALIZER; - -struct request { - enum { - MESSAGE_OPEN, - MESSAGE_CLOSE, - MESSAGE_WRITE, - MESSAGE_FLUSH, - MESSAGE_PAUSE, - MESSAGE_UNPAUSE, - MESSAGE_LATENCY, - MESSAGE_WRITABLE, - MESSAGE_TRIGGER, - } type; - void *data; - struct pa_sample_spec ss; - size_t length; - int success, done; - uint32_t value; - pa_volume_t volume; -}; - -static struct request* current_request = NULL; - -static int pipe_fds[2] = { -1, -1}; - -static pthread_t thread_id; -static int thread_running = 0; -static struct pa_context *context = NULL; -static struct pa_stream *stream = NULL; -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 void finish_request(int success) { - failed = 1; - - pthread_mutex_lock(&request_mutex); - - if (current_request) { - current_request->done = 1; - current_request->success = success; - pthread_cond_signal(&request_cond); - } - - pthread_mutex_unlock(&request_mutex); -} - -static void info_callback(struct pa_context *c, const struct pa_sink_input_info *i, int is_last, void *userdata) { - assert(c && c == context); - - if (!i) - return; - - volume = i->volume; -} - -static void subscribe_callback(struct pa_context *c, enum pa_subscription_event_type t, uint32_t index, void *userdata) { - assert(c && c == context); - - 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); -} - -static void stream_state_callback(struct pa_stream *s, void *userdata) { - assert(stream == s); - - switch(pa_stream_get_state(c)) { - 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); - finish_request(1); - break; - default: - finish_request(0); - } -} - -static void context_state_callback(struct pa_context *c, void *userdata) { - assert(c && c == context); - - switch (pa_context_get_state(c)) { - case PA_CONTEXT_CONNECTING: - case PA_CONTEXT_AUTHORIZING: - case PA_CONTEXT_SETTING_NAME: - break; - - 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); - - stream = pa_stream_new(c, ¤t_request->ss); - assert(stream); - - pa_stream_set_state(stream, stream_state_callback); - pa_stream_connect_playback(stream, NULL, NULL); - break; - - default: - finish_request(0); - } -} - -static void context_drain_callback(struct pa_context *c, void *userdata) { - assert(c && c == context); - mainloop_api->quit(mainloop_api, 0); -} - -static void stream_success_callback(struct pa_stream *s, int success, void *userdata) { - assert(s == stream && s); - finish_request(!!success); -} - -static void context_success_callback(struct pa_context *c, int success, void *userdata) { - assert(c == context && c); - finish_request(!!success); -} - -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); - 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) { - char x; - - assert(api && io && f == PA_IO_EVENT_INPUT); - - read(pipe_fds[0], &x, 1); - - pthread_mutex_lock(&request_mutex); - - if (current_request) { - if (failed) { - fail(); - } else { - switch (current_request->type) { - case MESSAGE_OPEN: - assert(!context && !stream); - context = pa_context_new(api, "xmms"); - assert(context); - pa_context_set_state_callback(context, context_state_callback, NULL); - pa_context_connect(context, NULL); - break; - - case MESSAGE_CLOSE: { - struct pa_operation *o; - assert(context); - if ((o = pa_context_drain(context, context_drain_callback, NULL))) - pa_operation_unref(o); - else - api->quit(mainloop_api, 0); - break; - } - - case MESSAGE_WRITE: - assert(context && stream && current_request->data && current_request->length > 0); - pa_stream_write(stream, current_request->data, current_request->length, free, 0); - current_request->data = NULL; - finish_request(1); - break; - - case MESSAGE_FLUSH: - assert(context && stream); - pa_operation_unref(pa_stream_flush(stream, stream_success_callback, NULL)); - break; - - 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)); - break; - - case MESSAGE_LATENCY: - assert(context && stream); - pa_operation_unref(pa_stream_get_latency(stream, latency_callback, NULL)); - break; - - case MESSAGE_WRITABLE: - assert(context && stream); - current_request->value = pa_stream_writable_size(stream); - finish_request(1); - break; - - case MESSAGE_GETVOLUME: - assert(context && stream); - current_request->volume = volume; - finish_request(1); - break; - - case MESSAGE_SETVOLUME: - assert(context && stream); - pa_operation_unref(pa_context_set_sink_input_volume(context, pa_stream_get_index(stream), current_request->volume, context_success_callback, NULL)); - break; - - case MESSAGE_TRIGGER: - assert(context && stream); - pa_operation_unref(pa_stream_trigger(stream, stream_success_callback, NULL)); - break; - - } - } - } - - pthread_mutex_unlock(&request_mutex); -} - -static void* thread_func(void *t) { - struct pa_mainloop *m; - struct pa_io_event *io; - - assert(pipe_fds[0] >= 0 && !mainloop_api); - - failed = 0; - - m = pa_mainloop_new(); - assert(m); - mainloop_api = pa_mainloop_get_api(m); - assert(mainloop_api); - - io = mainloop_api->io_new(mainloop_api, pipe_fds[0], PA_IO_EVENT_INPUT, &request_func, NULL); - assert(io); - - pa_mainloop_run(m, NULL); - - api->io_free(io); - pa_mainloop_free(m); - - mainloop_api = NULL; - - return NULL; -} - -static void start_thread(void) { - int r; - assert(!thread_running); - - r = pipe(pipe_fds); - assert(r >= 0 && pipe_fds[0] >= 0 && pipe_fds[1] >= 0); - - current_request = NULL; - - r = pthread_create(&thread_id, NULL, thread_func, NULL); - assert(!r); -} - -static void stop_thread(void) { - struct request req; - assert(thread_running); - - pthread_join(thread_id, NULL); - - thread_running = 0; - assert(!current_request); - - close(pipe_fds[0]); - close(pipe_fds[1]); - 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); - - r->success = r->done = 0; - - pthread_mutex_lock(&request_mutex); - assert(!current_request); - current_request = r; - - assert(pipe_fds[1] >= 0); - write(pipe_fds[1], &x, sizeof(x)); - - while (!r->done) - pthread_cond_wait(&request_cond, &request_mutex); - - current_request = NULL; - - pthread_mutex_unlock(&request_mutex); -} - -static void polyp_pause(short b) { - struct request r; - - r.message = b ? MESSAGE_PAUSE : MESSAGE_UNPAUSE; - request_execute(&r); -} - -static int polyp_free(void) { - int ret; - struct request r; - r.message = MESSAGE_WRITABLE; - request_execute(&r); - - ret = r.value; - - if (do_trigger) { - r.message = MESSAGE_TRIGGER; - request_execute(&r); - } - - do_trigger = 1; - return ret; -} - -static int polyp_playing(void) { - struct request r; - r.message = MESSAGE_LATENCY; - request_execute(&r); - - return r.value != 0; -} - -static int polyp_get_written_time(void) { - return ((written/pa_frame_size(&sample_spec))*1000)/sample_spec.rate; -} - -static int polyp_get_output_time(void) { - int t, ms; - struct request r; - r.message = MESSAGE_LATENCY; - request_execute(&r); - - t = polyp_get_output_time(); - ms = r.value/1000; - - if (ms > t) - return 0; - else - return t-ms; -} - -static void polyp_flush(int time) { - struct request r; - r.message = MESSAGE_FLUSH; - request_execute(&r); - - written = (time*sample_spec.rate/1000)*pa_frame_size(&sample_spec); -} - -static void polyp_write(void* ptr, int length) { - struct request r; - r.message = MESSAGE_WRITE; - r.data = ptr; - r.length = length; - - request_execute(&r); - - written += length; - do_trigger = 0; -} - -static int polyp_open(AFormat fmt, int rate, int nch) { - struct request r; - - 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) - r.ss.format = PA_SAMPLE_S16BE; - else if (fmt == FM_S16_NE) - r.ss.format = PA_SAMPLE_S16NE; - else - return 0; - - r.ss.rate = rate; - r.ss.channels = nch; - - if (!pa_sample_spec_valid(&r.ss)) - return 0; - - start_thread(); - - r.message = MESSAGE_OPEN; - request_execute(&r); - - if (!r->success) { - stop_thread(); - return 0; - } - - written = do_trigger = 0; - - return 1; -} - -static void polyp_close(void) { - struct request r; - - assert(thread_running); - - r.message = MESSAGE_CLOSE; - request_execute(&r); - - stop_thread(); -} - - -static void polyp_init(void) { -} - -static OutputPlugin polyp_plugin = { - NULL, - NULL, - "Polypaudio Output Plugin", /* Description */ - polyp_init, /* done */ - 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 */ -}; - -OutputPlugin *get_oplugin_info(void) { - return &polyp_plugin; -} |