Ejemplo n.º 1
0
void alc_pulse_probe(int type) //{{{
{
    if(!pulse_load()) return;

    if(type == DEVICE_PROBE)
        AppendDeviceList(pulse_device);
    else if(type == ALL_DEVICE_PROBE)
        AppendAllDeviceList(pulse_device);
    else if(type == CAPTURE_DEVICE_PROBE)
        AppendCaptureDeviceList(pulse_capture_device);

    pulse_unload();
} //}}}
Ejemplo n.º 2
0
ALCboolean alc_pulse_init(BackendFuncs *func_list) //{{{
{
    if(!pulse_load())
        return ALC_FALSE;

    *func_list = pulse_funcs;

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

    return ALC_TRUE;
} //}}}
void alc_pulse_probe( int type ) //{{{
{
	if ( !pulse_load() ) { return; }

	if ( type == DEVICE_PROBE )
	{
		AppendDeviceList( pulse_device );
	}
	else if ( type == ALL_DEVICE_PROBE )
	{
		ALuint i;

		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 );
		}
	}
	else if ( type == CAPTURE_DEVICE_PROBE )
	{
		ALuint i;

		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 );
		}
	}
} //}}}
Ejemplo n.º 4
0
// OpenAL {{{
static ALCboolean pulse_open_playback(ALCdevice *device, const ALCchar *device_name) //{{{
{
    if(!device_name)
        device_name = pulse_device;
    else if(strcmp(device_name, pulse_device) != 0)
        return ALC_FALSE;

    pulse_load();
    if(!pa_handle)
        return ALC_FALSE;

    if(pulse_open(device, device_name) != ALC_FALSE)
        return ALC_TRUE;

    pulse_unload();
    return ALC_FALSE;
} //}}}
Ejemplo n.º 5
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;
}
Ejemplo n.º 6
0
// OpenAL {{{
static ALCboolean pulse_open_playback(ALCdevice *device, const ALCchar *device_name) //{{{
{
    if(!device_name)
        device_name = pulse_device;
    else if(strcmp(device_name, pulse_device) != 0)
        return ALC_FALSE;

    if(!pulse_load())
        return ALC_FALSE;

    if(pulse_open(device, device_name) != ALC_FALSE)
    {
        ALuint len = GetConfigValueInt("pulse", "buffer-length", 2048);
        if(len != 0)
        {
            device->UpdateSize = len;
            device->NumUpdates = 1;
        }
        return ALC_TRUE;
    }

    pulse_unload();
    return ALC_FALSE;
} //}}}
// OpenAL {{{
static ALCboolean pulse_open_playback( ALCdevice* device, const ALCchar* device_name ) //{{{
{
	char* pulse_name = NULL;
	pa_sample_spec spec;
	pulse_data* data;
	ALuint len;

	if ( !pulse_load() )
	{
		return ALC_FALSE;
	}

	if ( !device_name )
	{
		device_name = pulse_device;
	}
	else if ( strcmp( device_name, pulse_device ) != 0 )
	{
		ALuint i;

		if ( !allDevNameMap )
		{
			probe_devices( AL_FALSE );
		}

		for ( i = 0; i < numDevNames; i++ )
		{
			if ( strcmp( device_name, allDevNameMap[i].name ) == 0 )
			{
				pulse_name = allDevNameMap[i].device_name;
				break;
			}
		}

		if ( i == numDevNames )
		{
			return ALC_FALSE;
		}
	}

	if ( pulse_open( device, device_name ) == ALC_FALSE )
	{
		return ALC_FALSE;
	}

	data = device->ExtraData;

	ppa_threaded_mainloop_lock( data->loop );

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

	data->device_name = pulse_name;
	pa_stream* stream = connect_playback_stream( device, 0, NULL, &spec, NULL );

	if ( !stream )
	{
		ppa_threaded_mainloop_unlock( data->loop );
		goto fail;
	}

	if ( ppa_stream_is_suspended( stream ) )
	{
		ppa_stream_disconnect( stream );
		ppa_stream_unref( stream );
		ppa_threaded_mainloop_unlock( data->loop );
		goto fail;
	}

	data->device_name = strdup( ppa_stream_get_device_name( stream ) );

	ppa_stream_disconnect( stream );
	ppa_stream_unref( stream );

	ppa_threaded_mainloop_unlock( data->loop );

	len = GetConfigValueInt( "pulse", "buffer-length", 2048 );

	if ( len != 0 )
	{
		device->UpdateSize = len;
		device->NumUpdates = 1;
	}

	return ALC_TRUE;

fail:
	pulse_close( device );
	return ALC_FALSE;
} //}}}
static ALCboolean pulse_open_capture( ALCdevice* device, const ALCchar* device_name ) //{{{
{
	char* pulse_name = NULL;
	pulse_data* data;
	pa_stream_flags_t flags = 0;
	pa_stream_state_t state;
	pa_channel_map chanmap;

	if ( !pulse_load() )
	{
		return ALC_FALSE;
	}

	if ( !allCaptureDevNameMap )
	{
		probe_devices( AL_TRUE );
	}

	if ( !device_name )
	{
		device_name = allCaptureDevNameMap[0].name;
	}
	else
	{
		ALuint i;

		for ( i = 0; i < numCaptureDevNames; i++ )
		{
			if ( strcmp( device_name, allCaptureDevNameMap[i].name ) == 0 )
			{
				pulse_name = allCaptureDevNameMap[i].device_name;
				break;
			}
		}

		if ( i == numCaptureDevNames )
		{
			return ALC_FALSE;
		}
	}

	if ( pulse_open( device, device_name ) == ALC_FALSE )
	{
		return ALC_FALSE;
	}

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

	data->samples = device->UpdateSize * device->NumUpdates;
	data->frame_size = aluFrameSizeFromFormat( device->Format );

	if ( !( data->ring = CreateRingBuffer( data->frame_size, data->samples ) ) )
	{
		ppa_threaded_mainloop_unlock( data->loop );
		goto fail;
	}

	data->attr.minreq = -1;
	data->attr.prebuf = -1;
	data->attr.maxlength = data->frame_size * data->samples;
	data->attr.tlength = -1;
	data->attr.fragsize = min( data->frame_size * data->samples,
	                           10 * device->Frequency / 1000 );

	data->spec.rate = device->Frequency;
	data->spec.channels = aluChannelsFromFormat( device->Format );

	switch ( aluBytesFromFormat( device->Format ) )
	{
		case 1:
			data->spec.format = PA_SAMPLE_U8;
			break;

		case 2:
			data->spec.format = PA_SAMPLE_S16NE;
			break;

		case 4:
			data->spec.format = PA_SAMPLE_FLOAT32NE;
			break;

		default:
			AL_PRINT( "Unknown format: 0x%x\n", device->Format );
			ppa_threaded_mainloop_unlock( data->loop );
			goto fail;
	}

	if ( ppa_sample_spec_valid( &data->spec ) == 0 )
	{
		AL_PRINT( "Invalid sample format\n" );
		ppa_threaded_mainloop_unlock( data->loop );
		goto fail;
	}

	if ( !ppa_channel_map_init_auto( &chanmap, data->spec.channels, PA_CHANNEL_MAP_WAVEEX ) )
	{
		AL_PRINT( "Couldn't build map for channel count (%d)!\n", data->spec.channels );
		ppa_threaded_mainloop_unlock( data->loop );
		goto fail;
	}

	data->stream = ppa_stream_new( data->context, "Capture Stream", &data->spec, &chanmap );

	if ( !data->stream )
	{
		AL_PRINT( "pa_stream_new() failed: %s\n",
		          ppa_strerror( ppa_context_errno( data->context ) ) );

		ppa_threaded_mainloop_unlock( data->loop );
		goto fail;
	}

	ppa_stream_set_state_callback( data->stream, stream_state_callback, data->loop );

	flags |= PA_STREAM_START_CORKED | PA_STREAM_ADJUST_LATENCY;

	if ( ppa_stream_connect_record( data->stream, pulse_name, &data->attr, flags ) < 0 )
	{
		AL_PRINT( "Stream did not connect: %s\n",
		          ppa_strerror( ppa_context_errno( data->context ) ) );

		ppa_stream_unref( data->stream );
		data->stream = NULL;

		ppa_threaded_mainloop_unlock( data->loop );
		goto fail;
	}

	while ( ( state = ppa_stream_get_state( data->stream ) ) != PA_STREAM_READY )
	{
		if ( !PA_STREAM_IS_GOOD( state ) )
		{
			AL_PRINT( "Stream did not get ready: %s\n",
			          ppa_strerror( ppa_context_errno( data->context ) ) );

			ppa_stream_unref( data->stream );
			data->stream = NULL;

			ppa_threaded_mainloop_unlock( data->loop );
			goto fail;
		}

		ppa_threaded_mainloop_wait( data->loop );
	}

	ppa_stream_set_state_callback( data->stream, stream_state_callback2, device );

	ppa_threaded_mainloop_unlock( data->loop );
	return ALC_TRUE;

fail:
	pulse_close( device );
	return ALC_FALSE;
} //}}}
Ejemplo n.º 9
0
static ALCboolean pulse_open_capture(ALCdevice *device, const ALCchar *device_name) //{{{
{
    pulse_data *data;
    pa_stream_state_t state;

    if(!device_name)
        device_name = pulse_capture_device;
    else if(strcmp(device_name, pulse_capture_device) != 0)
        return ALC_FALSE;

    pulse_load();
    if(!pa_handle)
        return ALC_FALSE;

    if(pulse_open(device, device_name) == ALC_FALSE)
    {
        pulse_unload();
        return ALC_FALSE;
    }

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

    data->samples = device->UpdateSize * device->NumUpdates;
    data->frame_size = aluBytesFromFormat(device->Format) *
                       aluChannelsFromFormat(device->Format);

    if(!(data->ring = CreateRingBuffer(data->frame_size, data->samples)))
    {
        ppa_threaded_mainloop_unlock(data->loop);
        pulse_close(device);
        pulse_unload();
        return ALC_FALSE;
    }

    data->attr.minreq = -1;
    data->attr.prebuf = -1;
    data->attr.maxlength = -1;
    data->attr.tlength = -1;
    data->attr.fragsize = data->frame_size * data->samples / 2;
    data->stream_name = "Capture Stream";

    data->spec.rate = device->Frequency;
    data->spec.channels = aluChannelsFromFormat(device->Format);

    switch(aluBytesFromFormat(device->Format))
    {
        case 1:
            data->spec.format = PA_SAMPLE_U8;
            break;
        case 2:
            data->spec.format = PA_SAMPLE_S16NE;
            break;
        case 4:
            data->spec.format = PA_SAMPLE_FLOAT32NE;
            break;
        default:
            AL_PRINT("Unknown format: 0x%x\n", device->Format);
            ppa_threaded_mainloop_unlock(data->loop);
            pulse_close(device);
            pulse_unload();
            return ALC_FALSE;
    }

    if(ppa_sample_spec_valid(&data->spec) == 0)
    {
        AL_PRINT("Invalid sample format\n");
        ppa_threaded_mainloop_unlock(data->loop);
        pulse_close(device);
        pulse_unload();
        return ALC_FALSE;
    }

    data->stream = ppa_stream_new(data->context, data->stream_name, &data->spec, NULL);
    if(!data->stream)
    {
        AL_PRINT("pa_stream_new() failed: %s\n",
                 ppa_strerror(ppa_context_errno(data->context)));

        ppa_threaded_mainloop_unlock(data->loop);
        pulse_close(device);
        pulse_unload();
        return ALC_FALSE;
    }

    ppa_stream_set_state_callback(data->stream, stream_state_callback, device);

    if(ppa_stream_connect_record(data->stream, NULL, &data->attr, PA_STREAM_ADJUST_LATENCY) < 0)
    {
        AL_PRINT("Stream did not connect: %s\n",
                 ppa_strerror(ppa_context_errno(data->context)));

        ppa_stream_unref(data->stream);
        ppa_threaded_mainloop_unlock(data->loop);

        data->stream = NULL;
        pulse_close(device);
        pulse_unload();
        return ALC_FALSE;
    }

    while((state=ppa_stream_get_state(data->stream)) != PA_STREAM_READY)
    {
        if(!PA_STREAM_IS_GOOD(state))
        {
            AL_PRINT("Stream did not get ready: %s\n",
                     ppa_strerror(ppa_context_errno(data->context)));

            ppa_stream_unref(data->stream);
            ppa_threaded_mainloop_unlock(data->loop);

            data->stream = NULL;
            pulse_close(device);
            pulse_unload();
            return ALC_FALSE;
        }

        ppa_threaded_mainloop_wait(data->loop);
        ppa_threaded_mainloop_accept(data->loop);
    }
    ppa_stream_set_state_callback(data->stream, stream_state_callback2, device);

    ppa_threaded_mainloop_unlock(data->loop);
    return ALC_TRUE;
} //}}}