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 ALCboolean pulse_open( ALCdevice* device, const ALCchar* device_name ) //{{{
{
	pulse_data* data = ppa_xmalloc( sizeof( pulse_data ) );
	memset( data, 0, sizeof( *data ) );

	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 );
	device->ExtraData = data;

	data->context = connect_context( data->loop );

	if ( !data->context )
	{
		ppa_threaded_mainloop_unlock( data->loop );
		goto out;
	}

	ppa_context_set_state_callback( data->context, context_state_callback2, device );

	device->szDeviceName = strdup( device_name );

	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 );
	}

	device->ExtraData = NULL;
	ppa_xfree( data );
	return ALC_FALSE;
} //}}}
Пример #3
0
ALCboolean alc_pulse_init(BackendFuncs *func_list)
{
    ALCboolean ret = ALC_FALSE;

    if(pulse_load())
    {
        pa_threaded_mainloop *loop;

        pulse_ctx_flags = 0;
        if(!GetConfigValueBool("pulse", "spawn-server", 0))
            pulse_ctx_flags |= PA_CONTEXT_NOAUTOSPAWN;

        if((loop=pa_threaded_mainloop_new()) &&
           pa_threaded_mainloop_start(loop) >= 0)
        {
            pa_context *context;

            pa_threaded_mainloop_lock(loop);
            context = connect_context(loop, AL_TRUE);
            if(context)
            {
                *func_list = pulse_funcs;
                ret = ALC_TRUE;

                /* Some libraries (Phonon, Qt) set some pulseaudio properties
                 * through environment variables, which causes all streams in
                 * the process to inherit them. This attempts to filter those
                 * properties out by setting them to 0-length data. */
                prop_filter = pa_proplist_new();
                pa_proplist_set(prop_filter, PA_PROP_MEDIA_ROLE, NULL, 0);
                pa_proplist_set(prop_filter, "phonon.streamid", NULL, 0);

                pa_context_disconnect(context);
                pa_context_unref(context);
            }
            pa_threaded_mainloop_unlock(loop);
            pa_threaded_mainloop_stop(loop);
        }
        if(loop)
            pa_threaded_mainloop_free(loop);
    }

    return ret;
}
Пример #4
0
static ALCboolean pulse_open(ALCdevice *device)
{
    pulse_data *data = pa_xmalloc(sizeof(pulse_data));
    memset(data, 0, sizeof(*data));

    if(!(data->loop = pa_threaded_mainloop_new()))
    {
        ERR("pa_threaded_mainloop_new() failed!\n");
        goto out;
    }
    if(pa_threaded_mainloop_start(data->loop) < 0)
    {
        ERR("pa_threaded_mainloop_start() failed\n");
        goto out;
    }

    pa_threaded_mainloop_lock(data->loop);
    device->ExtraData = data;

    data->context = connect_context(data->loop, AL_FALSE);
    if(!data->context)
    {
        pa_threaded_mainloop_unlock(data->loop);
        goto out;
    }
    pa_context_set_state_callback(data->context, context_state_callback2, device);

    pa_threaded_mainloop_unlock(data->loop);
    return ALC_TRUE;

out:
    if(data->loop)
    {
        pa_threaded_mainloop_stop(data->loop);
        pa_threaded_mainloop_free(data->loop);
    }

    device->ExtraData = NULL;
    pa_xfree(data);
    return ALC_FALSE;
}
Пример #5
0
static void probe_devices(ALboolean capture)
{
    pa_threaded_mainloop *loop;

    if(capture == AL_FALSE)
        allDevNameMap = malloc(sizeof(DevMap) * 1);
    else
        allCaptureDevNameMap = malloc(sizeof(DevMap) * 1);

    if((loop=pa_threaded_mainloop_new()) &&
       pa_threaded_mainloop_start(loop) >= 0)
    {
        pa_context *context;

        pa_threaded_mainloop_lock(loop);
        context = connect_context(loop, AL_FALSE);
        if(context)
        {
            pa_operation *o;

            if(capture == AL_FALSE)
                o = pa_context_get_sink_info_list(context, sink_device_callback, loop);
            else
                o = pa_context_get_source_info_list(context, source_device_callback, loop);
            while(pa_operation_get_state(o) == PA_OPERATION_RUNNING)
                pa_threaded_mainloop_wait(loop);
            pa_operation_unref(o);

            pa_context_disconnect(context);
            pa_context_unref(context);
        }
        pa_threaded_mainloop_unlock(loop);
        pa_threaded_mainloop_stop(loop);
    }
    if(loop)
        pa_threaded_mainloop_free(loop);
}
Пример #6
0
static ALCboolean pulse_load(void) //{{{
{
    ALCboolean ret = ALC_FALSE;
    if(!pa_handle)
    {
        pa_threaded_mainloop *loop;

#ifdef HAVE_DYNLOAD

#ifdef _WIN32
#define PALIB "libpulse-0.dll"
#elif defined(__APPLE__) && defined(__MACH__)
#define PALIB "libpulse.0.dylib"
#else
#define PALIB "libpulse.so.0"
#endif
        pa_handle = LoadLib(PALIB);
        if(!pa_handle)
            return ALC_FALSE;

#define LOAD_FUNC(x) do {                                                     \
    p##x = GetSymbol(pa_handle, #x);                                          \
    if(!(p##x)) {                                                             \
        CloseLib(pa_handle);                                                  \
        pa_handle = NULL;                                                     \
        return ALC_FALSE;                                                     \
    }                                                                         \
} while(0)
        LOAD_FUNC(pa_context_unref);
        LOAD_FUNC(pa_sample_spec_valid);
        LOAD_FUNC(pa_stream_drop);
        LOAD_FUNC(pa_strerror);
        LOAD_FUNC(pa_context_get_state);
        LOAD_FUNC(pa_stream_get_state);
        LOAD_FUNC(pa_threaded_mainloop_signal);
        LOAD_FUNC(pa_stream_peek);
        LOAD_FUNC(pa_threaded_mainloop_wait);
        LOAD_FUNC(pa_threaded_mainloop_unlock);
        LOAD_FUNC(pa_threaded_mainloop_in_thread);
        LOAD_FUNC(pa_context_new);
        LOAD_FUNC(pa_threaded_mainloop_stop);
        LOAD_FUNC(pa_context_disconnect);
        LOAD_FUNC(pa_threaded_mainloop_start);
        LOAD_FUNC(pa_threaded_mainloop_get_api);
        LOAD_FUNC(pa_context_set_state_callback);
        LOAD_FUNC(pa_stream_write);
        LOAD_FUNC(pa_xfree);
        LOAD_FUNC(pa_stream_connect_record);
        LOAD_FUNC(pa_stream_connect_playback);
        LOAD_FUNC(pa_stream_readable_size);
        LOAD_FUNC(pa_stream_writable_size);
        LOAD_FUNC(pa_stream_cork);
        LOAD_FUNC(pa_stream_is_suspended);
        LOAD_FUNC(pa_stream_get_device_name);
        LOAD_FUNC(pa_path_get_filename);
        LOAD_FUNC(pa_get_binary_name);
        LOAD_FUNC(pa_threaded_mainloop_free);
        LOAD_FUNC(pa_context_errno);
        LOAD_FUNC(pa_xmalloc);
        LOAD_FUNC(pa_stream_unref);
        LOAD_FUNC(pa_threaded_mainloop_accept);
        LOAD_FUNC(pa_stream_set_write_callback);
        LOAD_FUNC(pa_threaded_mainloop_new);
        LOAD_FUNC(pa_context_connect);
        LOAD_FUNC(pa_stream_set_buffer_attr);
        LOAD_FUNC(pa_stream_get_buffer_attr);
        LOAD_FUNC(pa_stream_get_sample_spec);
        LOAD_FUNC(pa_stream_get_time);
        LOAD_FUNC(pa_stream_set_read_callback);
        LOAD_FUNC(pa_stream_set_state_callback);
        LOAD_FUNC(pa_stream_set_moved_callback);
        LOAD_FUNC(pa_stream_set_underflow_callback);
        LOAD_FUNC(pa_stream_new);
        LOAD_FUNC(pa_stream_disconnect);
        LOAD_FUNC(pa_threaded_mainloop_lock);
        LOAD_FUNC(pa_channel_map_init_auto);
        LOAD_FUNC(pa_channel_map_parse);
        LOAD_FUNC(pa_channel_map_snprint);
        LOAD_FUNC(pa_channel_map_equal);
        LOAD_FUNC(pa_context_get_server_info);
        LOAD_FUNC(pa_context_get_sink_info_by_name);
        LOAD_FUNC(pa_context_get_sink_info_list);
        LOAD_FUNC(pa_context_get_source_info_list);
        LOAD_FUNC(pa_operation_get_state);
        LOAD_FUNC(pa_operation_unref);
#undef LOAD_FUNC
#define LOAD_OPTIONAL_FUNC(x) do {                                            \
    p##x = GetSymbol(pa_handle, #x);                                          \
} while(0)
#if PA_CHECK_VERSION(0,9,15)
        LOAD_OPTIONAL_FUNC(pa_channel_map_superset);
        LOAD_OPTIONAL_FUNC(pa_stream_set_buffer_attr_callback);
#endif
#if PA_CHECK_VERSION(0,9,16)
        LOAD_OPTIONAL_FUNC(pa_stream_begin_write);
#endif
#undef LOAD_OPTIONAL_FUNC

#else /* HAVE_DYNLOAD */
        pa_handle = (void*)0xDEADBEEF;
#endif

        if((loop=pa_threaded_mainloop_new()) &&
           pa_threaded_mainloop_start(loop) >= 0)
        {
            pa_context *context;

            pa_threaded_mainloop_lock(loop);
            context = connect_context(loop, AL_TRUE);
            if(context)
            {
                ret = ALC_TRUE;

                pa_context_disconnect(context);
                pa_context_unref(context);
            }
            pa_threaded_mainloop_unlock(loop);
            pa_threaded_mainloop_stop(loop);
        }
        if(loop)
            pa_threaded_mainloop_free(loop);

        if(!ret)
        {
#ifdef HAVE_DYNLOAD
            CloseLib(pa_handle);
#endif
            pa_handle = NULL;
        }
    }
    return ret;
} //}}}
Пример #7
0
void alc_pulse_probe(enum DevProbe type) //{{{
{
    pa_threaded_mainloop *loop;
    ALuint i;

    switch(type)
    {
        case DEVICE_PROBE:
            if((loop=pa_threaded_mainloop_new()) &&
               pa_threaded_mainloop_start(loop) >= 0)
            {
                pa_context *context;

                pa_threaded_mainloop_lock(loop);
                context = connect_context(loop, AL_FALSE);
                if(context)
                {
                    AppendDeviceList(pulse_device);

                    pa_context_disconnect(context);
                    pa_context_unref(context);
                }
                pa_threaded_mainloop_unlock(loop);
                pa_threaded_mainloop_stop(loop);
            }
            if(loop)
                pa_threaded_mainloop_free(loop);
            break;

        case ALL_DEVICE_PROBE:
            for(i = 0;i < numDevNames;++i)
            {
                free(allDevNameMap[i].name);
                free(allDevNameMap[i].device_name);
            }
            free(allDevNameMap);
            allDevNameMap = NULL;
            numDevNames = 0;

            probe_devices(AL_FALSE);

            for(i = 0;i < numDevNames;i++)
                AppendAllDeviceList(allDevNameMap[i].name);
            break;

        case CAPTURE_DEVICE_PROBE:
            for(i = 0;i < numCaptureDevNames;++i)
            {
                free(allCaptureDevNameMap[i].name);
                free(allCaptureDevNameMap[i].device_name);
            }
            free(allCaptureDevNameMap);
            allCaptureDevNameMap = NULL;
            numCaptureDevNames = 0;

            probe_devices(AL_TRUE);

            for(i = 0;i < numCaptureDevNames;i++)
                AppendCaptureDeviceList(allCaptureDevNameMap[i].name);
            break;
    }
} //}}}
Пример #8
0
static void probe_devices(ALboolean capture)
{
    pa_threaded_mainloop *loop;

    if(capture == AL_FALSE)
        allDevNameMap = malloc(sizeof(DevMap) * 1);
    else
        allCaptureDevNameMap = malloc(sizeof(DevMap) * 1);

    if((loop=pa_threaded_mainloop_new()) &&
       pa_threaded_mainloop_start(loop) >= 0)
    {
        pa_context *context;

        pa_threaded_mainloop_lock(loop);
        context = connect_context(loop, AL_FALSE);
        if(context)
        {
            pa_operation *o;

            if(capture == AL_FALSE)
            {
                pa_stream_flags_t flags;
                pa_sample_spec spec;
                pa_stream *stream;

                flags = PA_STREAM_FIX_FORMAT | PA_STREAM_FIX_RATE |
                        PA_STREAM_FIX_CHANNELS | PA_STREAM_DONT_MOVE;

                spec.format = PA_SAMPLE_S16NE;
                spec.rate = 44100;
                spec.channels = 2;

                stream = connect_playback_stream(NULL, loop, context, flags,
                                                 NULL, &spec, NULL);
                if(stream)
                {
                    o = pa_context_get_sink_info_by_name(context, pa_stream_get_device_name(stream), sink_device_callback, loop);
                    WAIT_FOR_OPERATION(o, loop);

                    pa_stream_disconnect(stream);
                    pa_stream_unref(stream);
                    stream = NULL;
                }

                o = pa_context_get_sink_info_list(context, sink_device_callback, loop);
            }
            else
            {
                pa_stream_flags_t flags;
                pa_sample_spec spec;
                pa_stream *stream;

                flags = PA_STREAM_FIX_FORMAT | PA_STREAM_FIX_RATE |
                        PA_STREAM_FIX_CHANNELS | PA_STREAM_DONT_MOVE;

                spec.format = PA_SAMPLE_S16NE;
                spec.rate = 44100;
                spec.channels = 1;

                stream = connect_record_stream(NULL, loop, context, flags,
                                               NULL, &spec, NULL);
                if(stream)
                {
                    o = pa_context_get_source_info_by_name(context, pa_stream_get_device_name(stream), source_device_callback, loop);
                    WAIT_FOR_OPERATION(o, loop);

                    pa_stream_disconnect(stream);
                    pa_stream_unref(stream);
                    stream = NULL;
                }

                o = pa_context_get_source_info_list(context, source_device_callback, loop);
            }
            WAIT_FOR_OPERATION(o, loop);

            pa_context_disconnect(context);
            pa_context_unref(context);
        }
        pa_threaded_mainloop_unlock(loop);
        pa_threaded_mainloop_stop(loop);
    }
    if(loop)
        pa_threaded_mainloop_free(loop);
}