static void pulse_close(ALCdevice *device) //{{{ { pulse_data *data = device->ExtraData; ppa_threaded_mainloop_lock(data->loop); if(data->stream) { ppa_stream_disconnect(data->stream); ppa_stream_unref(data->stream); } ppa_context_disconnect(data->context); ppa_context_unref(data->context); ppa_threaded_mainloop_unlock(data->loop); ppa_threaded_mainloop_stop(data->loop); ppa_threaded_mainloop_free(data->loop); device->ExtraData = NULL; free(device->szDeviceName); device->szDeviceName = NULL; DestroyRingBuffer(data->ring); ppa_xfree(data); } //}}}
static void probe_devices( ALboolean capture ) { pa_threaded_mainloop* loop; if ( capture == AL_FALSE ) { allDevNameMap = malloc( sizeof( DevMap ) * 1 ); allDevNameMap[0].name = strdup( "PulseAudio Default" ); allDevNameMap[0].device_name = NULL; numDevNames = 1; } else { allCaptureDevNameMap = malloc( sizeof( DevMap ) * 1 ); allCaptureDevNameMap[0].name = strdup( "PulseAudio Default" ); allCaptureDevNameMap[0].device_name = NULL; numCaptureDevNames = 1; } if ( ( loop = ppa_threaded_mainloop_new() ) && ppa_threaded_mainloop_start( loop ) >= 0 ) { pa_context* context; ppa_threaded_mainloop_lock( loop ); context = connect_context( loop ); if ( context ) { pa_operation* o; if ( capture == AL_FALSE ) { o = ppa_context_get_sink_info_list( context, sink_device_callback, loop ); } else { o = ppa_context_get_source_info_list( context, source_device_callback, loop ); } while ( ppa_operation_get_state( o ) == PA_OPERATION_RUNNING ) { ppa_threaded_mainloop_wait( loop ); } ppa_operation_unref( o ); ppa_context_disconnect( context ); ppa_context_unref( context ); } ppa_threaded_mainloop_unlock( loop ); ppa_threaded_mainloop_stop( loop ); } if ( loop ) { ppa_threaded_mainloop_free( loop ); } }
static pa_context* connect_context( pa_threaded_mainloop* loop ) { const char* name = "OpenAL Soft"; char path_name[PATH_MAX]; pa_context_state_t state; pa_context* context; int err; if ( ppa_get_binary_name( path_name, sizeof( path_name ) ) ) { name = ppa_path_get_filename( path_name ); } context = ppa_context_new( ppa_threaded_mainloop_get_api( loop ), name ); if ( !context ) { AL_PRINT( "pa_context_new() failed\n" ); return NULL; } ppa_context_set_state_callback( context, context_state_callback, loop ); if ( ( err = ppa_context_connect( context, NULL, pulse_ctx_flags, NULL ) ) >= 0 ) { while ( ( state = ppa_context_get_state( context ) ) != PA_CONTEXT_READY ) { if ( !PA_CONTEXT_IS_GOOD( state ) ) { err = ppa_context_errno( context ); break; } ppa_threaded_mainloop_wait( loop ); } } ppa_context_set_state_callback( context, NULL, NULL ); if ( err < 0 ) { AL_PRINT( "Context did not connect: %s\n", ppa_strerror( err ) ); ppa_context_unref( context ); return NULL; } return context; }
static ALCboolean pulse_open(ALCdevice *device, const ALCchar *device_name) //{{{ { pulse_data *data = ppa_xmalloc0(sizeof(pulse_data)); pa_context_state_t state; if(ppa_get_binary_name(data->path_name, sizeof(data->path_name))) data->context_name = ppa_path_get_filename(data->path_name); else data->context_name = "OpenAL Soft"; if(!(data->loop = ppa_threaded_mainloop_new())) { AL_PRINT("pa_threaded_mainloop_new() failed!\n"); goto out; } if(ppa_threaded_mainloop_start(data->loop) < 0) { AL_PRINT("pa_threaded_mainloop_start() failed\n"); goto out; } ppa_threaded_mainloop_lock(data->loop); data->context = ppa_context_new(ppa_threaded_mainloop_get_api(data->loop), data->context_name); if(!data->context) { AL_PRINT("pa_context_new() failed: %s\n", ppa_strerror(ppa_context_errno(data->context))); ppa_threaded_mainloop_unlock(data->loop); goto out; } if(ppa_context_connect(data->context, NULL, PA_CONTEXT_NOAUTOSPAWN, NULL) < 0) { AL_PRINT("Context did not connect: %s\n", ppa_strerror(ppa_context_errno(data->context))); ppa_context_unref(data->context); data->context = NULL; ppa_threaded_mainloop_unlock(data->loop); goto out; } while((state=ppa_context_get_state(data->context)) != PA_CONTEXT_READY) { if(!PA_CONTEXT_IS_GOOD(state)) { AL_PRINT("Context did not get ready: %s\n", ppa_strerror(ppa_context_errno(data->context))); ppa_context_unref(data->context); data->context = NULL; ppa_threaded_mainloop_unlock(data->loop); goto out; } ppa_threaded_mainloop_unlock(data->loop); Sleep(1); ppa_threaded_mainloop_lock(data->loop); } device->szDeviceName = strdup(device_name); device->ExtraData = data; ppa_threaded_mainloop_unlock(data->loop); return ALC_TRUE; out: if(data->loop) { ppa_threaded_mainloop_stop(data->loop); ppa_threaded_mainloop_free(data->loop); } ppa_xfree(data); return ALC_FALSE; } //}}}