Skip to content

Commit

Permalink
changes to entry and painterface
Browse files Browse the repository at this point in the history
- m_ModifyMutex is now public and lock/unlock methods have been removed
  m_ModifyMutex is now locked with a lock_guard

- Entry now holds a pointer to PAInterface, which is used instead of
  arguments to methods

- ~Entry will now set the entry pointer to nullptr for stream_callbacks
  if m_Monitor is set, which will cause to callback to return
  • Loading branch information
patroclos committed Sep 4, 2016
1 parent abbd0f0 commit 5f78d10
Show file tree
Hide file tree
Showing 9 changed files with 126 additions and 95 deletions.
92 changes: 56 additions & 36 deletions include/entry.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@ enum entry_type

struct Entry
{
PAInterface * interface;
std::string m_Name;
uint32_t m_Index;
double m_Peak;
double m_Peak = 0;
pa_stream * m_Monitor = nullptr;
uint32_t m_MonitorIndex;
bool m_Mute;
Expand All @@ -29,104 +30,123 @@ struct Entry
bool m_Lock = true;
bool m_Kill;

Entry(PAInterface *iface);
~Entry();
// general methods
virtual void setVolume(PAInterface *interface, const int channel, const pa_volume_t volume) = 0;
virtual void setMute(PAInterface *interface, bool mute) = 0;
virtual void addVolume(PAInterface *interface, const int channel, const double deltaPct);
virtual void cycleSwitch(PAInterface *interface, bool increment) = 0;
virtual void setVolume(const int channel, const pa_volume_t volume) = 0;
virtual void setMute(bool mute) = 0;
virtual void addVolume(const int channel, const double deltaPct);
virtual void cycleSwitch(bool increment) = 0;

virtual void update(const pa_sink_info *info) {}
virtual void update(const pa_source_info *info) {}
virtual void update(const pa_sink_input_info *info) {}
virtual void update(const pa_source_output_info *info) {}

// device methods
virtual void suspend(PAInterface *interface) {}
virtual void setPort(PAInterface *interface, const char *port) {}
virtual void suspend() {}
virtual void setPort(const char *port) {}

// stream methods
virtual void move(PAInterface *interface, uint32_t idx) {}
virtual void kill(PAInterface *interface) {}
virtual void move(uint32_t idx) {}
virtual void kill() {}
};

struct DeviceEntry : public Entry
{
int m_Port;
std::vector<std::string> m_Ports;

DeviceEntry(PAInterface *iface)
: Entry(iface){};

// general methods
virtual void setVolume(PAInterface *interface, const int channel, const pa_volume_t volume) = 0;
virtual void setMute(PAInterface *interface, bool mute) = 0;
virtual void cycleSwitch(PAInterface *interface, bool increment) = 0;
virtual void setVolume(const int channel, const pa_volume_t volume) = 0;
virtual void setMute(bool mute) = 0;
virtual void cycleSwitch(bool increment) = 0;

virtual std::string getPort() { return m_Port > -1 ? m_Ports[m_Port] : ""; }
virtual void setPort(PAInterface *interface, const char *port) = 0;
virtual void setPort(const char *port) = 0;
};

struct StreamEntry : public Entry
{
uint32_t m_Device;

StreamEntry(PAInterface *iface)
: Entry(iface){};

// general methods
virtual void setVolume(PAInterface *interface, const int channel, const pa_volume_t volume) = 0;
virtual void setMute(PAInterface *interface, bool mute) = 0;
virtual void cycleSwitch(PAInterface *interface, bool increment) = 0;
virtual void setVolume(const int channel, const pa_volume_t volume) = 0;
virtual void setMute(bool mute) = 0;
virtual void cycleSwitch(bool increment) = 0;

virtual void move(PAInterface *interface, uint32_t idx) = 0;
virtual void kill(PAInterface *interface) = 0;
virtual void move(uint32_t idx) = 0;
virtual void kill() = 0;
};

struct SinkEntry : public DeviceEntry
{
pa_sink_state_t m_State;

SinkEntry(PAInterface *iface)
: DeviceEntry(iface) {}

void update(const pa_sink_info *info);

// general methods
virtual void setVolume(PAInterface *interface, const int channel, const pa_volume_t volume);
virtual void setMute(PAInterface *interface, bool mute);
virtual void cycleSwitch(PAInterface *interface, bool increment);
virtual void setVolume(const int channel, const pa_volume_t volume);
virtual void setMute(bool mute);
virtual void cycleSwitch(bool increment);

virtual void setPort(PAInterface *interface, const char *port);
virtual void setPort(const char *port);
};

struct SourceEntry : public DeviceEntry
{
pa_source_state_t m_State;

SourceEntry(PAInterface *iface)
: DeviceEntry(iface) {}

void update(const pa_source_info *info);

// general methods
virtual void setVolume(PAInterface *interface, const int channel, const pa_volume_t volume);
virtual void setMute(PAInterface *interface, bool mute);
virtual void cycleSwitch(PAInterface *interface, bool increment);
virtual void setVolume(const int channel, const pa_volume_t volume);
virtual void setMute(bool mute);
virtual void cycleSwitch(bool increment);

virtual void setPort(PAInterface *interface, const char *port);
virtual void setPort(const char *port);
};

struct SinkInputEntry : public StreamEntry
{
void update(const pa_sink_input_info *info);

SinkInputEntry(PAInterface *iface)
: StreamEntry(iface) {}

// general methods
virtual void setVolume(PAInterface *interface, const int channel, const pa_volume_t volume);
virtual void setMute(PAInterface *interface, bool mute);
virtual void cycleSwitch(PAInterface *interface, bool increment);
virtual void setVolume(const int channel, const pa_volume_t volume);
virtual void setMute(bool mute);
virtual void cycleSwitch(bool increment);

virtual void move(PAInterface *interface, uint32_t idx);
virtual void kill(PAInterface *interface);
virtual void move(uint32_t idx);
virtual void kill();
};

struct SourceOutputEntry : public StreamEntry
{
void update(const pa_source_output_info *info);

SourceOutputEntry(PAInterface *iface)
: StreamEntry(iface) {}

// general methods
virtual void setVolume(PAInterface *interface, const int channel, const pa_volume_t volume);
virtual void setMute(PAInterface *interface, bool mute);
virtual void cycleSwitch(PAInterface *interface, bool increment);
virtual void setVolume(const int channel, const pa_volume_t volume);
virtual void setMute(bool mute);
virtual void cycleSwitch(bool increment);

virtual void move(PAInterface *interface, uint32_t idx);
virtual void kill(PAInterface *interface);
virtual void move(uint32_t idx);
virtual void kill();
};
7 changes: 2 additions & 5 deletions include/painterface.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,6 @@ class PAInterface
std::map<uint32_t, std::unique_ptr<Entry>> m_SinkInputs;
std::map<uint32_t, std::unique_ptr<Entry>> m_SourceOutputs;

std::mutex m_modifyMutex;

pai_subscription_cb m_Subscription_callback;

private:
Expand Down Expand Up @@ -83,6 +81,8 @@ class PAInterface

void subscribe(pai_subscription_cb callback);

std::mutex m_ModifyMutex;

std::map<uint32_t, std::unique_ptr<Entry>> &getSinks() { return m_Sinks; }
std::map<uint32_t, std::unique_ptr<Entry>> &getSources() { return m_Sources; }
std::map<uint32_t, std::unique_ptr<Entry>> &getSinkInputs() { return m_SinkInputs; }
Expand All @@ -91,9 +91,6 @@ class PAInterface
std::vector<std::unique_ptr<std::pair<PAInterface *, Entry *>>> m_IEPairs;
void createMonitorStreamForEntry(Entry *entry, int type);

void modifyLock();
void modifyUnlock();

//PulseAudio API Callbacks
//userptr points to current PAInterface instance
static void cb_context_state(pa_context *context, void *interface);
Expand Down
12 changes: 10 additions & 2 deletions src/entry.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
#include <entry.hpp>

Entry::Entry(PAInterface *iface)
: interface(iface)
{
}

Entry::~Entry()
{
if (m_Monitor)
{
mainloop_lockguard mlg(interface->getPAMainloop());

pa_stream_set_state_callback(m_Monitor, &PAInterface::cb_stream_state, nullptr);
if (PA_STREAM_IS_GOOD(pa_stream_get_state(m_Monitor)))
{
pa_stream_disconnect(m_Monitor);
Expand All @@ -13,8 +21,8 @@ Entry::~Entry()
}
}

void Entry::addVolume(PAInterface *interface, const int channel, const double deltaPct)
void Entry::addVolume(const int channel, const double deltaPct)
{
volume_pct_delta(&m_PAVolume, channel, deltaPct);
setVolume(interface, channel, m_Lock ? pa_cvolume_avg(&m_PAVolume) : m_PAVolume.values[channel]);
setVolume(channel, m_Lock ? pa_cvolume_avg(&m_PAVolume) : m_PAVolume.values[channel]);
}
48 changes: 26 additions & 22 deletions src/painterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,10 @@ void PAInterface::cb_sink_info(pa_context *context, const pa_sink_info *info, in
if (!eol)
{
std::map<uint32_t, std::unique_ptr<Entry>> &map = ((PAInterface *)interface)->m_Sinks;

std::lock_guard<std::mutex> lg(((PAInterface *)interface)->m_ModifyMutex);
if (!map.count(info->index) || !map[info->index])
map[info->index] = std::unique_ptr<Entry>(new SinkEntry());
map[info->index] = std::unique_ptr<Entry>(new SinkEntry((PAInterface *)interface));
map[info->index]->update(info);
}
else
Expand All @@ -107,8 +109,9 @@ void PAInterface::cb_source_info(pa_context *context, const pa_source_info *info
if (!eol)
{
std::map<uint32_t, std::unique_ptr<Entry>> &map = ((PAInterface *)interface)->m_Sources;
std::lock_guard<std::mutex> lg(((PAInterface *)interface)->m_ModifyMutex);
if (!map.count(info->index) || !map[info->index])
map[info->index] = std::unique_ptr<Entry>(new SourceEntry());
map[info->index] = std::unique_ptr<Entry>(new SourceEntry((PAInterface *)interface));
map[info->index]->update(info);
}
else
Expand All @@ -120,8 +123,9 @@ void PAInterface::cb_sink_input_info(pa_context *context, const pa_sink_input_in
if (!eol)
{
std::map<uint32_t, std::unique_ptr<Entry>> &map = ((PAInterface *)interface)->m_SinkInputs;
std::lock_guard<std::mutex> lg(((PAInterface *)interface)->m_ModifyMutex);
if (!map.count(info->index) || !map[info->index])
map[info->index] = std::unique_ptr<Entry>(new SinkInputEntry());
map[info->index] = std::unique_ptr<Entry>(new SinkInputEntry((PAInterface *)interface));
map[info->index]->update(info);
}
else
Expand All @@ -139,8 +143,9 @@ void PAInterface::cb_source_output_info(pa_context *context, const pa_source_out
return;
}
std::map<uint32_t, std::unique_ptr<Entry>> &map = ((PAInterface *)interface)->m_SourceOutputs;
std::lock_guard<std::mutex> lg(((PAInterface *)interface)->m_ModifyMutex);
if (!map.count(info->index) || !map[info->index])
map[info->index] = std::unique_ptr<Entry>(new SourceOutputEntry());
map[info->index] = std::unique_ptr<Entry>(new SourceOutputEntry((PAInterface *)interface));
map[info->index]->update(info);
}
else
Expand Down Expand Up @@ -182,6 +187,8 @@ void PAInterface::cb_read(pa_stream *stream, size_t nbytes, void *iepair)

void PAInterface::cb_stream_state(pa_stream *stream, void *entry)
{
if (!entry)
return;
pa_stream_state_t state = pa_stream_get_state(stream);
if (state == PA_STREAM_TERMINATED || state == PA_STREAM_FAILED)
{
Expand All @@ -193,11 +200,14 @@ void __updateEntries(PAInterface *interface, std::map<uint32_t, std::unique_ptr<
{
mainloop_lockguard lg(interface->getPAMainloop());

for (iter_entry_t it = map.begin(); it != map.end();)
if (it->second)
it++->second->m_Kill = true;
else
it = map.erase(it);
{
std::lock_guard<std::mutex> mlg(interface->m_ModifyMutex);
for (iter_entry_t it = map.begin(); it != map.end();)
if (it->second)
it++->second->m_Kill = true;
else
it = map.erase(it);
}

pa_operation *infooper = nullptr;
switch (entrytype)
Expand All @@ -223,9 +233,14 @@ void __updateEntries(PAInterface *interface, std::map<uint32_t, std::unique_ptr<
pa_threaded_mainloop_wait(interface->getPAMainloop());
pa_operation_unref(infooper);

interface->modifyLock();
std::lock_guard<std::mutex> modlg(interface->m_ModifyMutex);
for (iter_entry_t it = map.begin(); it != map.end();)
{
if (!it->second)
{
it = map.erase(it);
continue;
}
if (it->second->m_Kill)
{
for (std::vector<std::unique_ptr<std::pair<PAInterface *, Entry *>>>::iterator pairit = interface->m_IEPairs.begin(); pairit != interface->m_IEPairs.end();)
Expand All @@ -246,7 +261,6 @@ void __updateEntries(PAInterface *interface, std::map<uint32_t, std::unique_ptr<
it++;
}
}
interface->modifyUnlock();
}

void PAInterface::_updateSinks(PAInterface *interface)
Expand Down Expand Up @@ -376,7 +390,7 @@ void PAInterface::createMonitorStreamForEntry(Entry *entry, int type)
if (type == ENTRY_SINKINPUT)
{
uint32_t dev = ((SinkInputEntry *)entry)->m_Device;
if (m_Sinks.count(dev))
if (m_Sinks.count(dev) && m_Sinks[dev])
entry->m_Monitor = _createMonitor(this, m_Sinks[dev]->m_Index, entry, entry->m_Index);
}
else
Expand All @@ -397,13 +411,3 @@ void PAInterface::notifySubscription(const pai_subscription_type_t type)
m_Subscription_callback(this, type);
}
}

void PAInterface::modifyLock()
{
m_modifyMutex.lock();
}

void PAInterface::modifyUnlock()
{
m_modifyMutex.unlock();
}
Loading

0 comments on commit 5f78d10

Please sign in to comment.