static int pulse_context_init(cubeb * ctx) { if (ctx->context) { assert(ctx->error == 1); pulse_context_destroy(ctx); } ctx->context = WRAP(pa_context_new)(WRAP(pa_threaded_mainloop_get_api)(ctx->mainloop), ctx->context_name); if (!ctx->context) { return -1; } WRAP(pa_context_set_state_callback)(ctx->context, context_state_callback, ctx); WRAP(pa_threaded_mainloop_lock)(ctx->mainloop); WRAP(pa_context_connect)(ctx->context, NULL, 0, NULL); if (wait_until_context_ready(ctx) != 0) { WRAP(pa_threaded_mainloop_unlock)(ctx->mainloop); pulse_context_destroy(ctx); ctx->context = NULL; return -1; } WRAP(pa_threaded_mainloop_unlock)(ctx->mainloop); ctx->error = 0; return 0; }
/*static*/ int pulse_init(cubeb ** context, char const * context_name) { void * libpulse = NULL; cubeb * ctx; *context = NULL; #ifndef DISABLE_LIBPULSE_DLOPEN libpulse = dlopen("libpulse.so.0", RTLD_LAZY); if (!libpulse) { return CUBEB_ERROR; } #define LOAD(x) do { \ cubeb_##x = dlsym(libpulse, #x); \ if (!cubeb_##x) { \ dlclose(libpulse); \ return CUBEB_ERROR; \ } \ } while(0) LOAD(pa_channel_map_init_auto); LOAD(pa_context_connect); LOAD(pa_context_disconnect); LOAD(pa_context_drain); LOAD(pa_context_get_state); LOAD(pa_context_new); LOAD(pa_context_rttime_new); LOAD(pa_context_set_state_callback); LOAD(pa_context_get_sink_info_by_name); LOAD(pa_context_get_server_info); LOAD(pa_context_unref); LOAD(pa_frame_size); LOAD(pa_operation_get_state); LOAD(pa_operation_unref); LOAD(pa_rtclock_now); LOAD(pa_stream_begin_write); LOAD(pa_stream_cancel_write); LOAD(pa_stream_connect_playback); LOAD(pa_stream_cork); LOAD(pa_stream_disconnect); LOAD(pa_stream_get_latency); LOAD(pa_stream_get_state); LOAD(pa_stream_get_time); LOAD(pa_stream_new); LOAD(pa_stream_set_state_callback); LOAD(pa_stream_set_write_callback); LOAD(pa_stream_unref); LOAD(pa_stream_update_timing_info); LOAD(pa_stream_write); LOAD(pa_threaded_mainloop_free); LOAD(pa_threaded_mainloop_get_api); LOAD(pa_threaded_mainloop_lock); LOAD(pa_threaded_mainloop_in_thread); LOAD(pa_threaded_mainloop_new); LOAD(pa_threaded_mainloop_signal); LOAD(pa_threaded_mainloop_start); LOAD(pa_threaded_mainloop_stop); LOAD(pa_threaded_mainloop_unlock); LOAD(pa_threaded_mainloop_wait); LOAD(pa_usec_to_bytes); #undef LOAD #endif ctx = calloc(1, sizeof(*ctx)); assert(ctx); ctx->ops = &pulse_ops; ctx->libpulse = libpulse; ctx->mainloop = WRAP(pa_threaded_mainloop_new)(); ctx->context = WRAP(pa_context_new)(WRAP(pa_threaded_mainloop_get_api)(ctx->mainloop), context_name); WRAP(pa_context_set_state_callback)(ctx->context, context_state_callback, ctx); WRAP(pa_threaded_mainloop_start)(ctx->mainloop); WRAP(pa_threaded_mainloop_lock)(ctx->mainloop); WRAP(pa_context_connect)(ctx->context, NULL, 0, NULL); if (wait_until_context_ready(ctx) != 0) { WRAP(pa_threaded_mainloop_unlock)(ctx->mainloop); pulse_destroy(ctx); return CUBEB_ERROR; } WRAP(pa_context_get_server_info)(ctx->context, server_info_callback, ctx); WRAP(pa_threaded_mainloop_unlock)(ctx->mainloop); *context = ctx; return CUBEB_OK; }