static ALCuint pulse_available_samples( ALCdevice* device ) //{{{
{
	pulse_data* data = device->ExtraData;
	size_t samples;

	ppa_threaded_mainloop_lock( data->loop );
	/* Capture is done in fragment-sized chunks, so we loop until we get all
	 * that's available */
	samples = ( device->Connected ? ppa_stream_readable_size( data->stream ) : 0 );

	while ( samples > 0 )
	{
		const void* buf;
		size_t length;

		if ( ppa_stream_peek( data->stream, &buf, &length ) < 0 )
		{
			AL_PRINT( "pa_stream_peek() failed: %s\n",
			          ppa_strerror( ppa_context_errno( data->context ) ) );
			break;
		}

		WriteRingBuffer( data->ring, buf, length / data->frame_size );
		samples -= length;

		ppa_stream_drop( data->stream );
	}

	ppa_threaded_mainloop_unlock( data->loop );

	return RingBufferSize( data->ring );
} //}}}
Example #2
0
static void stream_read_callback(pa_stream *stream, size_t length, void *pdata) //{{{
{
    ALCdevice *Device = pdata;
    pulse_data *data = Device->ExtraData;
    const void *buf;

    if(ppa_stream_peek(stream, &buf, &length) < 0)
    {
        AL_PRINT("pa_stream_peek() failed: %s\n",
                 ppa_strerror(ppa_context_errno(data->context)));
        return;
    }

    assert(buf);
    assert(length);

    length /= data->frame_size;

    if(data->samples < length)
        AL_PRINT("stream_read_callback: buffer overflow!\n");

    WriteRingBuffer(data->ring, buf, (length<data->samples) ? length : data->samples);

    ppa_stream_drop(stream);
} //}}}
Example #3
0
static void pulse_capture_samples(ALCdevice *device, ALCvoid *buffer, ALCuint samples) //{{{
{
    pulse_data *data = device->ExtraData;
    ALCuint available = RingBufferSize(data->ring);
    const void *buf;
    size_t length;

    available *= data->frame_size;
    samples *= data->frame_size;

    ppa_threaded_mainloop_lock(data->loop);
    if(available+ppa_stream_readable_size(data->stream) < samples)
    {
        ppa_threaded_mainloop_unlock(data->loop);
        alcSetError(device, ALC_INVALID_VALUE);
        return;
    }

    available = min(available, samples);
    if(available > 0)
    {
        ReadRingBuffer(data->ring, buffer, available/data->frame_size);
        buffer = (ALubyte*)buffer + available;
        samples -= available;
    }

    /* Capture is done in fragment-sized chunks, so we loop until we get all
     * that's requested */
    while(samples > 0)
    {
        if(ppa_stream_peek(data->stream, &buf, &length) < 0)
        {
            AL_PRINT("pa_stream_peek() failed: %s\n",
                     ppa_strerror(ppa_context_errno(data->context)));
            break;
        }
        available = min(length, samples);

        memcpy(buffer, buf, available);
        buffer = (ALubyte*)buffer + available;
        buf = (const ALubyte*)buf + available;
        samples -= available;
        length -= available;

        /* Any unread data in the fragment will be lost, so save it */
        length /= data->frame_size;
        if(length > 0)
        {
            if(length > data->samples)
                length = data->samples;
            WriteRingBuffer(data->ring, buf, length);
        }

        ppa_stream_drop(data->stream);
    }
    ppa_threaded_mainloop_unlock(data->loop);
} //}}}