pa_threaded_mainloop *m = (pa_threaded_mainloop *)userdata;
pa_threaded_mainloop_signal(m, 0);
}
+
+static void SinkChangedCallback(pa_context *c, pa_subscription_event_type_t t, uint32_t idx, void *userdata)
+{
+ CAESinkPULSE* p = (CAESinkPULSE*) userdata;
+ if(!p)
+ return;
+
+ CSingleLock lock(p->m_sec);
+ if (p->IsInitialized())
+ {
+ if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW)
+ {
+ CLog::Log(LOGDEBUG, "Sink appeared");
+ CAEFactory::DeviceChange();
+ }
+ else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE)
+ {
+ CLog::Log(LOGDEBUG, "Sink removed");
+ CAEFactory::DeviceChange();
+ }
+ }
+}
+
struct SinkInfoStruct
{
AEDeviceInfoList *list;
bool CAESinkPULSE::Initialize(AEAudioFormat &format, std::string &device)
{
- m_IsAllocated = false;
+ {
+ CSingleLock lock(m_sec);
+ m_IsAllocated = false;
+ }
m_passthrough = false;
m_BytesPerSecond = 0;
m_BufferSize = 0;
pa_threaded_mainloop_lock(m_MainLoop);
+ {
+ // Register Callback for Sink changes
+ CSingleLock lock(m_sec);
+ pa_context_set_subscribe_callback(m_Context, SinkChangedCallback, this);
+ const pa_subscription_mask_t mask = PA_SUBSCRIPTION_MASK_SINK;
+ pa_operation *op = pa_context_subscribe(m_Context, mask, NULL, this);
+ if (op != NULL)
+ pa_operation_unref(op);
+ }
+
struct pa_channel_map map;
pa_channel_map_init(&map);
}
pa_threaded_mainloop_unlock(m_MainLoop);
-
- m_IsAllocated = true;
+
format.m_frameSize = frameSize;
format.m_frameSamples = format.m_frames * format.m_channelLayout.Count();
m_format = format;
format.m_dataFormat = m_passthrough ? AE_FMT_S16NE : format.m_dataFormat;
Pause(false);
+ {
+ CSingleLock lock(m_sec);
+ m_IsAllocated = true;
+ }
return true;
}
void CAESinkPULSE::Deinitialize()
{
+ CSingleLock lock(m_sec);
m_IsAllocated = false;
m_passthrough = false;
}
}
+bool CAESinkPULSE::IsInitialized()
+{
+ CSingleLock lock(m_sec);
+ return m_IsAllocated;
+}
+
bool CAESinkPULSE::Pause(bool pause)
{
pa_threaded_mainloop_lock(m_MainLoop);
#include "system.h"
#include "cores/AudioEngine/Interfaces/AESink.h"
+#include "cores/AudioEngine/AEFactory.h"
#include "Utils/AEDeviceInfo.h"
#include "Utils/AEUtil.h"
#include <pulse/pulseaudio.h>
+#include "threads/CriticalSection.h"
class CAESinkPULSE : public IAESink
{
virtual void SetVolume(float volume);
static void EnumerateDevicesEx(AEDeviceInfoList &list, bool force = false);
+ bool IsInitialized();
+ CCriticalSection m_sec;
private:
bool Pause(bool pause);
static inline bool WaitForOperation(pa_operation *op, pa_threaded_mainloop *mainloop, const char *LogEntry);