Skip to content

Commit

Permalink
Rewrite PulseAudioDevice to use ThreadedDevice.
Browse files Browse the repository at this point in the history
  • Loading branch information
neXyon committed Mar 29, 2021
1 parent 9516924 commit 09e4f27
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 52 deletions.
62 changes: 30 additions & 32 deletions plugins/pulseaudio/PulseAudioDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ void PulseAudioDevice::PulseAudio_state_callback(pa_context *context, void *data
{
PulseAudioDevice* device = (PulseAudioDevice*)data;

device->m_state = AUD_pa_context_get_state(context);
std::lock_guard<ILockable> lock(*device);

AUD_pa_threaded_mainloop_signal(device->m_mainloop, 0);
device->m_state = AUD_pa_context_get_state(context);
}

void PulseAudioDevice::PulseAudio_request(pa_stream *stream, size_t num_bytes, void *data)
Expand Down Expand Up @@ -68,29 +68,40 @@ void PulseAudioDevice::PulseAudio_underflow(pa_stream *stream, void *data)
}
}

void PulseAudioDevice::playing(bool playing)
void PulseAudioDevice::runMixingThread()
{
m_playback = playing;
for(;;)
{
{
std::lock_guard<ILockable> lock(*this);

if(shouldStop())
{
AUD_pa_stream_cork(m_stream, 1, nullptr, nullptr);
doStop();
return;
}
}

if(AUD_pa_stream_is_corked(m_stream))
AUD_pa_stream_cork(m_stream, 0, nullptr, nullptr);

AUD_pa_stream_cork(m_stream, playing ? 0 : 1, nullptr, nullptr);
AUD_pa_mainloop_iterate(m_mainloop, true, nullptr);
}
}

PulseAudioDevice::PulseAudioDevice(std::string name, DeviceSpecs specs, int buffersize) :
m_playback(false),
m_state(PA_CONTEXT_UNCONNECTED),
m_buffersize(buffersize),
m_underflows(0)
{
m_mainloop = AUD_pa_threaded_mainloop_new();
m_mainloop = AUD_pa_mainloop_new();

AUD_pa_threaded_mainloop_lock(m_mainloop);

m_context = AUD_pa_context_new(AUD_pa_threaded_mainloop_get_api(m_mainloop), name.c_str());
m_context = AUD_pa_context_new(AUD_pa_mainloop_get_api(m_mainloop), name.c_str());

if(!m_context)
{
AUD_pa_threaded_mainloop_unlock(m_mainloop);
AUD_pa_threaded_mainloop_free(m_mainloop);
AUD_pa_mainloop_free(m_mainloop);

AUD_THROW(DeviceException, "Could not connect to PulseAudio.");
}
Expand All @@ -99,26 +110,21 @@ PulseAudioDevice::PulseAudioDevice(std::string name, DeviceSpecs specs, int buff

AUD_pa_context_connect(m_context, nullptr, PA_CONTEXT_NOFLAGS, nullptr);

AUD_pa_threaded_mainloop_start(m_mainloop);

while(m_state != PA_CONTEXT_READY)
{
switch(m_state)
{
case PA_CONTEXT_FAILED:
case PA_CONTEXT_TERMINATED:
AUD_pa_threaded_mainloop_unlock(m_mainloop);
AUD_pa_threaded_mainloop_stop(m_mainloop);

AUD_pa_context_disconnect(m_context);
AUD_pa_context_unref(m_context);

AUD_pa_threaded_mainloop_free(m_mainloop);
AUD_pa_mainloop_free(m_mainloop);

AUD_THROW(DeviceException, "Could not connect to PulseAudio.");
break;
default:
AUD_pa_threaded_mainloop_wait(m_mainloop);
AUD_pa_mainloop_iterate(m_mainloop, true, nullptr);
break;
}
}
Expand Down Expand Up @@ -166,13 +172,10 @@ PulseAudioDevice::PulseAudioDevice(std::string name, DeviceSpecs specs, int buff

if(!m_stream)
{
AUD_pa_threaded_mainloop_unlock(m_mainloop);
AUD_pa_threaded_mainloop_stop(m_mainloop);

AUD_pa_context_disconnect(m_context);
AUD_pa_context_unref(m_context);

AUD_pa_threaded_mainloop_free(m_mainloop);
AUD_pa_mainloop_free(m_mainloop);

AUD_THROW(DeviceException, "Could not create PulseAudio stream.");
}
Expand All @@ -188,32 +191,27 @@ PulseAudioDevice::PulseAudioDevice(std::string name, DeviceSpecs specs, int buff
buffer_attr.prebuf = -1U;
buffer_attr.tlength = buffersize;

if(AUD_pa_stream_connect_playback(m_stream, nullptr, &buffer_attr, static_cast<pa_stream_flags_t>(PA_STREAM_INTERPOLATE_TIMING | PA_STREAM_ADJUST_LATENCY | PA_STREAM_AUTO_TIMING_UPDATE), nullptr, nullptr) < 0)
if(AUD_pa_stream_connect_playback(m_stream, nullptr, &buffer_attr, static_cast<pa_stream_flags_t>(PA_STREAM_START_CORKED | PA_STREAM_INTERPOLATE_TIMING | PA_STREAM_ADJUST_LATENCY | PA_STREAM_AUTO_TIMING_UPDATE), nullptr, nullptr) < 0)
{
AUD_pa_threaded_mainloop_unlock(m_mainloop);
AUD_pa_threaded_mainloop_stop(m_mainloop);

AUD_pa_context_disconnect(m_context);
AUD_pa_context_unref(m_context);

AUD_pa_threaded_mainloop_free(m_mainloop);
AUD_pa_mainloop_free(m_mainloop);

AUD_THROW(DeviceException, "Could not connect PulseAudio stream.");
}

AUD_pa_threaded_mainloop_unlock(m_mainloop);

create();
}

PulseAudioDevice::~PulseAudioDevice()
{
AUD_pa_threaded_mainloop_stop(m_mainloop);
stopMixingThread();

AUD_pa_context_disconnect(m_context);
AUD_pa_context_unref(m_context);

AUD_pa_threaded_mainloop_free(m_mainloop);
AUD_pa_mainloop_free(m_mainloop);

destroy();
}
Expand Down
19 changes: 8 additions & 11 deletions plugins/pulseaudio/PulseAudioDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
* The PulseAudioDevice class.
*/

#include "devices/SoftwareDevice.h"
#include "devices/ThreadedDevice.h"

#include <pulse/pulseaudio.h>

Expand All @@ -35,15 +35,10 @@ AUD_NAMESPACE_BEGIN
/**
* This device plays back through PulseAudio, the simple direct media layer.
*/
class AUD_PLUGIN_API PulseAudioDevice : public SoftwareDevice
class AUD_PLUGIN_API PulseAudioDevice : public ThreadedDevice
{
private:
/**
* Whether there is currently playback.
*/
volatile bool m_playback;

pa_threaded_mainloop* m_mainloop;
pa_mainloop* m_mainloop;
pa_context* m_context;
pa_stream* m_stream;
pa_context_state_t m_state;
Expand Down Expand Up @@ -74,13 +69,15 @@ class AUD_PLUGIN_API PulseAudioDevice : public SoftwareDevice
*/
AUD_LOCAL static void PulseAudio_underflow(pa_stream* stream, void* data);

/**
* Streaming thread main function.
*/
AUD_LOCAL void runMixingThread();

// delete copy constructor and operator=
PulseAudioDevice(const PulseAudioDevice&) = delete;
PulseAudioDevice& operator=(const PulseAudioDevice&) = delete;

protected:
virtual void playing(bool playing);

public:
/**
* Opens the PulseAudio audio device for playback.
Expand Down
14 changes: 5 additions & 9 deletions plugins/pulseaudio/PulseAudioSymbols.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,14 @@ PULSEAUDIO_SYMBOL(pa_context_unref);
PULSEAUDIO_SYMBOL(pa_stream_begin_write);
PULSEAUDIO_SYMBOL(pa_stream_connect_playback);
PULSEAUDIO_SYMBOL(pa_stream_cork);
PULSEAUDIO_SYMBOL(pa_stream_is_corked);
PULSEAUDIO_SYMBOL(pa_stream_new);
PULSEAUDIO_SYMBOL(pa_stream_set_buffer_attr);
PULSEAUDIO_SYMBOL(pa_stream_set_underflow_callback);
PULSEAUDIO_SYMBOL(pa_stream_set_write_callback);
PULSEAUDIO_SYMBOL(pa_stream_write);

PULSEAUDIO_SYMBOL(pa_threaded_mainloop_free);
PULSEAUDIO_SYMBOL(pa_threaded_mainloop_get_api);
PULSEAUDIO_SYMBOL(pa_threaded_mainloop_lock);
PULSEAUDIO_SYMBOL(pa_threaded_mainloop_new);
PULSEAUDIO_SYMBOL(pa_threaded_mainloop_signal);
PULSEAUDIO_SYMBOL(pa_threaded_mainloop_start);
PULSEAUDIO_SYMBOL(pa_threaded_mainloop_stop);
PULSEAUDIO_SYMBOL(pa_threaded_mainloop_unlock);
PULSEAUDIO_SYMBOL(pa_threaded_mainloop_wait);
PULSEAUDIO_SYMBOL(pa_mainloop_free);
PULSEAUDIO_SYMBOL(pa_mainloop_get_api);
PULSEAUDIO_SYMBOL(pa_mainloop_new);
PULSEAUDIO_SYMBOL(pa_mainloop_iterate);

0 comments on commit 09e4f27

Please sign in to comment.