summaryrefslogtreecommitdiff
path: root/indra/media_plugins
diff options
context:
space:
mode:
Diffstat (limited to 'indra/media_plugins')
-rw-r--r--indra/media_plugins/cef/linux/volume_catcher_linux.cpp40
-rwxr-xr-xindra/media_plugins/cef/linux/volume_catcher_pipewire.cpp206
-rwxr-xr-xindra/media_plugins/cef/linux/volume_catcher_pulseaudio.cpp394
3 files changed, 320 insertions, 320 deletions
diff --git a/indra/media_plugins/cef/linux/volume_catcher_linux.cpp b/indra/media_plugins/cef/linux/volume_catcher_linux.cpp
index 439c0a6768..b4d20935e7 100644
--- a/indra/media_plugins/cef/linux/volume_catcher_linux.cpp
+++ b/indra/media_plugins/cef/linux/volume_catcher_linux.cpp
@@ -36,45 +36,45 @@ VolumeCatcher::VolumeCatcher()
void VolumeCatcher::onEnablePipeWireVolumeCatcher(bool enable)
{
- if (pimpl != nullptr)
- return;
+ if (pimpl != nullptr)
+ return;
- if (enable)
+ if (enable)
{
- LL_DEBUGS() << "volume catcher using pipewire" << LL_ENDL;
- pimpl = new VolumeCatcherPipeWire();
- }
+ LL_DEBUGS() << "volume catcher using pipewire" << LL_ENDL;
+ pimpl = new VolumeCatcherPipeWire();
+ }
else
{
- LL_DEBUGS() << "volume catcher using pulseaudio" << LL_ENDL;
- pimpl = new VolumeCatcherPulseAudio();
- }
+ LL_DEBUGS() << "volume catcher using pulseaudio" << LL_ENDL;
+ pimpl = new VolumeCatcherPulseAudio();
+ }
}
VolumeCatcher::~VolumeCatcher()
{
- if (pimpl != nullptr)
+ if (pimpl != nullptr)
{
- delete pimpl;
- pimpl = nullptr;
- }
+ delete pimpl;
+ pimpl = nullptr;
+ }
}
void VolumeCatcher::setVolume(F32 volume)
{
- if (pimpl != nullptr) {
- pimpl->setVolume(volume);
- }
+ if (pimpl != nullptr) {
+ pimpl->setVolume(volume);
+ }
}
void VolumeCatcher::setPan(F32 pan)
{
- if (pimpl != nullptr)
- pimpl->setPan(pan);
+ if (pimpl != nullptr)
+ pimpl->setPan(pan);
}
void VolumeCatcher::pump()
{
- if (pimpl != nullptr)
- pimpl->pump();
+ if (pimpl != nullptr)
+ pimpl->pump();
}
diff --git a/indra/media_plugins/cef/linux/volume_catcher_pipewire.cpp b/indra/media_plugins/cef/linux/volume_catcher_pipewire.cpp
index 8617468f17..0fb9d26476 100755
--- a/indra/media_plugins/cef/linux/volume_catcher_pipewire.cpp
+++ b/indra/media_plugins/cef/linux/volume_catcher_pipewire.cpp
@@ -52,77 +52,77 @@ SymbolGrabber pwSymbolGrabber;
VolumeCatcherPipeWire::VolumeCatcherPipeWire()
{
- init();
+ init();
}
VolumeCatcherPipeWire::~VolumeCatcherPipeWire()
{
- cleanup();
+ cleanup();
}
static void registryEventGlobal(
- void *data, uint32_t id, uint32_t permissions, const char *type,
- uint32_t version, const struct spa_dict *props)
+ void *data, uint32_t id, uint32_t permissions, const char *type,
+ uint32_t version, const struct spa_dict *props)
{
- static_cast<VolumeCatcherPipeWire*>(data)->handleRegistryEventGlobal(
- id, permissions, type, version, props
- );
+ static_cast<VolumeCatcherPipeWire*>(data)->handleRegistryEventGlobal(
+ id, permissions, type, version, props
+ );
}
static const struct pw_registry_events REGISTRY_EVENTS = {
- .version = PW_VERSION_REGISTRY_EVENTS,
+ .version = PW_VERSION_REGISTRY_EVENTS,
.global = registryEventGlobal,
};
bool VolumeCatcherPipeWire::loadsyms(std::string pw_dso_name)
{
- return pwSymbolGrabber.grabSymbols({ pw_dso_name });
+ return pwSymbolGrabber.grabSymbols({ pw_dso_name });
}
void VolumeCatcherPipeWire::init()
{
LL_DEBUGS() << "init" << LL_ENDL;
- mGotSyms = loadsyms("libpipewire-0.3.so.0");
-
- if (!mGotSyms)
- return;
+ mGotSyms = loadsyms("libpipewire-0.3.so.0");
+
+ if (!mGotSyms)
+ return;
LL_DEBUGS() << "successfully got symbols" << LL_ENDL;
- llpw_init(nullptr, nullptr);
+ llpw_init(nullptr, nullptr);
- mThreadLoop = llpw_thread_loop_new("SL Plugin Volume Adjuster", nullptr);
+ mThreadLoop = llpw_thread_loop_new("SL Plugin Volume Adjuster", nullptr);
- if (!mThreadLoop)
- return;
+ if (!mThreadLoop)
+ return;
- // i dont think we need to lock this early
- // std::lock_guard pwLock(*this);
+ // i dont think we need to lock this early
+ // std::lock_guard pwLock(*this);
- mContext = llpw_context_new(
- llpw_thread_loop_get_loop(mThreadLoop), nullptr, 0
- );
+ mContext = llpw_context_new(
+ llpw_thread_loop_get_loop(mThreadLoop), nullptr, 0
+ );
- if (!mContext)
- return;
+ if (!mContext)
+ return;
- mCore = llpw_context_connect(mContext, nullptr, 0);
+ mCore = llpw_context_connect(mContext, nullptr, 0);
- if (!mCore)
- return;
+ if (!mCore)
+ return;
- mRegistry = pw_core_get_registry(mCore, PW_VERSION_REGISTRY, 0);
+ mRegistry = pw_core_get_registry(mCore, PW_VERSION_REGISTRY, 0);
LL_DEBUGS() << "pw_core_get_registry: " << (mRegistry?"success":"nullptr") << LL_ENDL;
- spa_zero(mRegistryListener);
+ spa_zero(mRegistryListener);
- pw_registry_add_listener(
- mRegistry, &mRegistryListener, &REGISTRY_EVENTS, this
- );
+ pw_registry_add_listener(
+ mRegistry, &mRegistryListener, &REGISTRY_EVENTS, this
+ );
- llpw_thread_loop_start(mThreadLoop);
+ llpw_thread_loop_start(mThreadLoop);
LL_DEBUGS() << "thread loop started" << LL_ENDL;
}
@@ -150,52 +150,52 @@ void VolumeCatcherPipeWire::cleanup()
llpw_context_destroy(mContext);
}
- if (!mThreadLoop)
- return;
+ if (!mThreadLoop)
+ return;
- llpw_thread_loop_stop(mThreadLoop);
- llpw_thread_loop_destroy(mThreadLoop);
+ llpw_thread_loop_stop(mThreadLoop);
+ llpw_thread_loop_destroy(mThreadLoop);
LL_DEBUGS() << "cleanup done" << LL_ENDL;
}
void VolumeCatcherPipeWire::lock()
{
- if (!mThreadLoop)
- return;
+ if (!mThreadLoop)
+ return;
- llpw_thread_loop_lock(mThreadLoop);
+ llpw_thread_loop_lock(mThreadLoop);
}
void VolumeCatcherPipeWire::unlock()
{
- if (!mThreadLoop)
- return;
+ if (!mThreadLoop)
+ return;
- llpw_thread_loop_unlock(mThreadLoop);
+ llpw_thread_loop_unlock(mThreadLoop);
}
void VolumeCatcherPipeWire::ChildNode::updateVolume()
{
- if (!mActive)
- return;
+ if (!mActive)
+ return;
- F32 volume = std::clamp(mImpl->mVolume, 0.0f, 1.0f);
+ F32 volume = std::clamp(mImpl->mVolume, 0.0f, 1.0f);
- const uint32_t channels = 1;
- float volumes[channels];
- volumes[0] = volume;
+ const uint32_t channels = 1;
+ float volumes[channels];
+ volumes[0] = volume;
- uint8_t buffer[512];
+ uint8_t buffer[512];
- spa_pod_builder builder;
- spa_pod_builder_init(&builder, buffer, sizeof(buffer));
+ spa_pod_builder builder;
+ spa_pod_builder_init(&builder, buffer, sizeof(buffer));
- spa_pod_frame frame;
- spa_pod_builder_push_object(&builder, &frame, SPA_TYPE_OBJECT_Props, SPA_PARAM_Props);
- spa_pod_builder_prop(&builder, SPA_PROP_channelVolumes, 0);
- spa_pod_builder_array(&builder, sizeof(float), SPA_TYPE_Float, channels, volumes);
- spa_pod* pod = static_cast<spa_pod*>(spa_pod_builder_pop(&builder, &frame));
+ spa_pod_frame frame;
+ spa_pod_builder_push_object(&builder, &frame, SPA_TYPE_OBJECT_Props, SPA_PARAM_Props);
+ spa_pod_builder_prop(&builder, SPA_PROP_channelVolumes, 0);
+ spa_pod_builder_array(&builder, sizeof(float), SPA_TYPE_Float, channels, volumes);
+ spa_pod* pod = static_cast<spa_pod*>(spa_pod_builder_pop(&builder, &frame));
{
std::lock_guard pwLock(*mImpl);
@@ -205,18 +205,18 @@ void VolumeCatcherPipeWire::ChildNode::updateVolume()
void VolumeCatcherPipeWire::ChildNode::destroy()
{
- if (!mActive)
- return;
+ if (!mActive)
+ return;
- mActive = false;
+ mActive = false;
{
std::unique_lock childNodesLock(mImpl->mChildNodesMutex);
mImpl->mChildNodes.erase(this);
}
- spa_hook_remove(&mNodeListener);
- spa_hook_remove(&mProxyListener);
+ spa_hook_remove(&mNodeListener);
+ spa_hook_remove(&mProxyListener);
{
std::lock_guard pwLock(*mImpl);
@@ -226,23 +226,23 @@ void VolumeCatcherPipeWire::ChildNode::destroy()
static void nodeEventInfo(void* data, const struct pw_node_info* info)
{
- const char* processId = spa_dict_lookup(info->props, PW_KEY_APP_PROCESS_ID);
+ const char* processId = spa_dict_lookup(info->props, PW_KEY_APP_PROCESS_ID);
+
+ if (processId == nullptr)
+ return;
- if (processId == nullptr)
- return;
-
- pid_t pid = atoll(processId);
+ pid_t pid = atoll(processId);
- if (!isPluginPid(pid))
- return;
+ if (!isPluginPid(pid))
+ return;
const char* appName = spa_dict_lookup(info->props, PW_KEY_APP_NAME);
LL_DEBUGS() << "got app: " << appName << LL_ENDL;
-
- auto* const childNode = static_cast<VolumeCatcherPipeWire::ChildNode*>(data);
+
+ auto* const childNode = static_cast<VolumeCatcherPipeWire::ChildNode*>(data);
LL_DEBUGS() << "init volume: " << childNode->mImpl->mVolume << LL_ENDL;
- childNode->updateVolume();
+ childNode->updateVolume();
{
std::lock_guard childNodesLock(childNode->mImpl->mChildNodesMutex);
@@ -251,59 +251,59 @@ static void nodeEventInfo(void* data, const struct pw_node_info* info)
}
static const struct pw_node_events NODE_EVENTS = {
- .version = PW_VERSION_CLIENT_EVENTS,
- .info = nodeEventInfo,
+ .version = PW_VERSION_CLIENT_EVENTS,
+ .info = nodeEventInfo,
};
static void proxyEventDestroy(void* data)
{
- auto* const childNode = static_cast<VolumeCatcherPipeWire::ChildNode*>(data);
- childNode->destroy();
+ auto* const childNode = static_cast<VolumeCatcherPipeWire::ChildNode*>(data);
+ childNode->destroy();
}
static void proxyEventRemoved(void* data)
{
- auto* const childNode = static_cast<VolumeCatcherPipeWire::ChildNode*>(data);
- childNode->destroy();
+ auto* const childNode = static_cast<VolumeCatcherPipeWire::ChildNode*>(data);
+ childNode->destroy();
}
static const struct pw_proxy_events PROXY_EVENTS = {
- .version = PW_VERSION_PROXY_EVENTS,
+ .version = PW_VERSION_PROXY_EVENTS,
.destroy = proxyEventDestroy,
- .removed = proxyEventRemoved,
+ .removed = proxyEventRemoved,
};
void VolumeCatcherPipeWire::handleRegistryEventGlobal(
- uint32_t id, uint32_t permissions, const char *type, uint32_t version,
- const struct spa_dict *props)
+ uint32_t id, uint32_t permissions, const char *type, uint32_t version,
+ const struct spa_dict *props)
{
- if (props == nullptr || type == nullptr || strcmp(type, PW_TYPE_INTERFACE_Node) != 0)
- return;
-
- const char* mediaClass = spa_dict_lookup(props, PW_KEY_MEDIA_CLASS);
-
- if (mediaClass == nullptr || strcmp(mediaClass, "Stream/Output/Audio") != 0)
- return;
-
- pw_proxy* proxy = static_cast<pw_proxy*>(
- pw_registry_bind(mRegistry, id, type, PW_VERSION_CLIENT, sizeof(ChildNode))
- );
-
- auto* const childNode = static_cast<ChildNode*>(llpw_proxy_get_user_data(proxy));
-
- childNode->mActive = true;
- childNode->mProxy = proxy;
- childNode->mImpl = this;
-
- pw_node_add_listener(proxy, &childNode->mNodeListener, &NODE_EVENTS, childNode);
- llpw_proxy_add_listener(proxy, &childNode->mProxyListener, &PROXY_EVENTS, childNode);
+ if (props == nullptr || type == nullptr || strcmp(type, PW_TYPE_INTERFACE_Node) != 0)
+ return;
+
+ const char* mediaClass = spa_dict_lookup(props, PW_KEY_MEDIA_CLASS);
+
+ if (mediaClass == nullptr || strcmp(mediaClass, "Stream/Output/Audio") != 0)
+ return;
+
+ pw_proxy* proxy = static_cast<pw_proxy*>(
+ pw_registry_bind(mRegistry, id, type, PW_VERSION_CLIENT, sizeof(ChildNode))
+ );
+
+ auto* const childNode = static_cast<ChildNode*>(llpw_proxy_get_user_data(proxy));
+
+ childNode->mActive = true;
+ childNode->mProxy = proxy;
+ childNode->mImpl = this;
+
+ pw_node_add_listener(proxy, &childNode->mNodeListener, &NODE_EVENTS, childNode);
+ llpw_proxy_add_listener(proxy, &childNode->mProxyListener, &PROXY_EVENTS, childNode);
}
void VolumeCatcherPipeWire::setVolume(F32 volume)
{
LL_DEBUGS() << "setting volume to: " << volume << LL_ENDL;
- mVolume = volume;
+ mVolume = volume;
{
std::unique_lock childNodeslock(mChildNodesMutex);
diff --git a/indra/media_plugins/cef/linux/volume_catcher_pulseaudio.cpp b/indra/media_plugins/cef/linux/volume_catcher_pulseaudio.cpp
index f7f64ef76c..9417c49d38 100755
--- a/indra/media_plugins/cef/linux/volume_catcher_pulseaudio.cpp
+++ b/indra/media_plugins/cef/linux/volume_catcher_pulseaudio.cpp
@@ -57,124 +57,124 @@ SymbolGrabber paSymbolGrabber;
// PulseAudio requires a chain of callbacks with C linkage
extern "C" {
- void callback_discovered_sinkinput(pa_context *context, const pa_sink_input_info *i, int eol, void *userdata);
- void callback_subscription_alert(pa_context *context, pa_subscription_event_type_t t, uint32_t index, void *userdata);
- void callback_context_state(pa_context *context, void *userdata);
+ void callback_discovered_sinkinput(pa_context *context, const pa_sink_input_info *i, int eol, void *userdata);
+ void callback_subscription_alert(pa_context *context, pa_subscription_event_type_t t, uint32_t index, void *userdata);
+ void callback_context_state(pa_context *context, void *userdata);
}
VolumeCatcherPulseAudio::VolumeCatcherPulseAudio()
- : mDesiredVolume(0.0f),
- mMainloop(nullptr),
- mPAContext(nullptr),
- mConnected(false),
- mGotSyms(false)
+ : mDesiredVolume(0.0f),
+ mMainloop(nullptr),
+ mPAContext(nullptr),
+ mConnected(false),
+ mGotSyms(false)
{
- init();
+ init();
}
VolumeCatcherPulseAudio::~VolumeCatcherPulseAudio()
{
- cleanup();
+ cleanup();
}
bool VolumeCatcherPulseAudio::loadsyms(std::string pulse_dso_name)
{
- return paSymbolGrabber.grabSymbols({ pulse_dso_name });
+ return paSymbolGrabber.grabSymbols({ pulse_dso_name });
}
void VolumeCatcherPulseAudio::init()
{
- // try to be as defensive as possible because PA's interface is a
- // bit fragile and (for our purposes) we'd rather simply not function
- // than crash
-
- // we cheat and rely upon libpulse-mainloop-glib.so.0 to pull-in
- // libpulse.so.0 - this isn't a great assumption, and the two DSOs should
- // probably be loaded separately. Our Linux DSO framework needs refactoring,
- // we do this sort of thing a lot with practically identical logic...
- mGotSyms = loadsyms("libpulse-mainloop-glib.so.0");
-
- if (!mGotSyms)
- mGotSyms = loadsyms("libpulse.so.0");
-
- if (!mGotSyms)
- return;
-
- mMainloop = llpa_glib_mainloop_new(g_main_context_default());
-
- if (mMainloop)
- {
- pa_mainloop_api *api = llpa_glib_mainloop_get_api(mMainloop);
-
- if (api)
- {
- pa_proplist *proplist = llpa_proplist_new();
-
- if (proplist)
- {
- llpa_proplist_sets(proplist, PA_PROP_APPLICATION_ICON_NAME, "multimedia-player");
- llpa_proplist_sets(proplist, PA_PROP_APPLICATION_ID, "com.secondlife.viewer.mediaplugvoladjust");
- llpa_proplist_sets(proplist, PA_PROP_APPLICATION_NAME, "SL Plugin Volume Adjuster");
- llpa_proplist_sets(proplist, PA_PROP_APPLICATION_VERSION, "1");
-
- // plain old pa_context_new() is broken!
- mPAContext = llpa_context_new_with_proplist(api, nullptr, proplist);
-
- llpa_proplist_free(proplist);
- }
- }
- }
-
- // Now we've set up a PA context and mainloop, try connecting the
- // PA context to a PA daemon.
- if (mPAContext)
- {
- llpa_context_set_state_callback(mPAContext, callback_context_state, this);
- pa_context_flags_t cflags = (pa_context_flags)0; // maybe add PA_CONTEXT_NOAUTOSPAWN?
- if (llpa_context_connect(mPAContext, nullptr, cflags, nullptr) >= 0)
- {
- // Okay! We haven't definitely connected, but we
- // haven't definitely failed yet.
- }
- else
- {
- // Failed to connect to PA manager... we'll leave
- // things like that. Perhaps we should try again later.
- }
- }
+ // try to be as defensive as possible because PA's interface is a
+ // bit fragile and (for our purposes) we'd rather simply not function
+ // than crash
+
+ // we cheat and rely upon libpulse-mainloop-glib.so.0 to pull-in
+ // libpulse.so.0 - this isn't a great assumption, and the two DSOs should
+ // probably be loaded separately. Our Linux DSO framework needs refactoring,
+ // we do this sort of thing a lot with practically identical logic...
+ mGotSyms = loadsyms("libpulse-mainloop-glib.so.0");
+
+ if (!mGotSyms)
+ mGotSyms = loadsyms("libpulse.so.0");
+
+ if (!mGotSyms)
+ return;
+
+ mMainloop = llpa_glib_mainloop_new(g_main_context_default());
+
+ if (mMainloop)
+ {
+ pa_mainloop_api *api = llpa_glib_mainloop_get_api(mMainloop);
+
+ if (api)
+ {
+ pa_proplist *proplist = llpa_proplist_new();
+
+ if (proplist)
+ {
+ llpa_proplist_sets(proplist, PA_PROP_APPLICATION_ICON_NAME, "multimedia-player");
+ llpa_proplist_sets(proplist, PA_PROP_APPLICATION_ID, "com.secondlife.viewer.mediaplugvoladjust");
+ llpa_proplist_sets(proplist, PA_PROP_APPLICATION_NAME, "SL Plugin Volume Adjuster");
+ llpa_proplist_sets(proplist, PA_PROP_APPLICATION_VERSION, "1");
+
+ // plain old pa_context_new() is broken!
+ mPAContext = llpa_context_new_with_proplist(api, nullptr, proplist);
+
+ llpa_proplist_free(proplist);
+ }
+ }
+ }
+
+ // Now we've set up a PA context and mainloop, try connecting the
+ // PA context to a PA daemon.
+ if (mPAContext)
+ {
+ llpa_context_set_state_callback(mPAContext, callback_context_state, this);
+ pa_context_flags_t cflags = (pa_context_flags)0; // maybe add PA_CONTEXT_NOAUTOSPAWN?
+ if (llpa_context_connect(mPAContext, nullptr, cflags, nullptr) >= 0)
+ {
+ // Okay! We haven't definitely connected, but we
+ // haven't definitely failed yet.
+ }
+ else
+ {
+ // Failed to connect to PA manager... we'll leave
+ // things like that. Perhaps we should try again later.
+ }
+ }
}
void VolumeCatcherPulseAudio::cleanup()
{
- mConnected = false;
+ mConnected = false;
- if (mGotSyms && mPAContext)
- {
- llpa_context_disconnect(mPAContext);
- llpa_context_unref(mPAContext);
- }
+ if (mGotSyms && mPAContext)
+ {
+ llpa_context_disconnect(mPAContext);
+ llpa_context_unref(mPAContext);
+ }
- mPAContext = nullptr;
+ mPAContext = nullptr;
- if (mGotSyms && mMainloop)
- llpa_glib_mainloop_free(mMainloop);
+ if (mGotSyms && mMainloop)
+ llpa_glib_mainloop_free(mMainloop);
- mMainloop = nullptr;
+ mMainloop = nullptr;
}
void VolumeCatcherPulseAudio::setVolume(F32 volume)
{
- mDesiredVolume = volume;
-
- if (!mGotSyms)
- return;
+ mDesiredVolume = volume;
- if (mConnected && mPAContext)
- {
- update_all_volumes(mDesiredVolume);
- }
+ if (!mGotSyms)
+ return;
- pump();
+ if (mConnected && mPAContext)
+ {
+ update_all_volumes(mDesiredVolume);
+ }
+
+ pump();
}
void VolumeCatcherPulseAudio::setPan(F32 pan)
@@ -183,140 +183,140 @@ void VolumeCatcherPulseAudio::setPan(F32 pan)
void VolumeCatcherPulseAudio::pump()
{
- gboolean may_block = FALSE;
- g_main_context_iteration(g_main_context_default(), may_block);
+ gboolean may_block = FALSE;
+ g_main_context_iteration(g_main_context_default(), may_block);
}
void VolumeCatcherPulseAudio::connected_okay()
{
- pa_operation *op;
-
- // fetch global list of existing sinkinputs
- if ((op = llpa_context_get_sink_input_info_list(mPAContext,
- callback_discovered_sinkinput,
- this)))
- {
- llpa_operation_unref(op);
- }
-
- // subscribe to future global sinkinput changes
- llpa_context_set_subscribe_callback(mPAContext,
- callback_subscription_alert,
- this);
- if ((op = llpa_context_subscribe(mPAContext, (pa_subscription_mask_t)
- (PA_SUBSCRIPTION_MASK_SINK_INPUT),
+ pa_operation *op;
+
+ // fetch global list of existing sinkinputs
+ if ((op = llpa_context_get_sink_input_info_list(mPAContext,
+ callback_discovered_sinkinput,
+ this)))
+ {
+ llpa_operation_unref(op);
+ }
+
+ // subscribe to future global sinkinput changes
+ llpa_context_set_subscribe_callback(mPAContext,
+ callback_subscription_alert,
+ this);
+ if ((op = llpa_context_subscribe(mPAContext, (pa_subscription_mask_t)
+ (PA_SUBSCRIPTION_MASK_SINK_INPUT),
nullptr, nullptr)))
- {
- llpa_operation_unref(op);
- }
+ {
+ llpa_operation_unref(op);
+ }
}
void VolumeCatcherPulseAudio::update_all_volumes(F32 volume)
{
- for (std::set<U32>::iterator it = mSinkInputIndices.begin();
- it != mSinkInputIndices.end(); ++it)
- {
- update_index_volume(*it, volume);
- }
+ for (std::set<U32>::iterator it = mSinkInputIndices.begin();
+ it != mSinkInputIndices.end(); ++it)
+ {
+ update_index_volume(*it, volume);
+ }
}
void VolumeCatcherPulseAudio::update_index_volume(U32 index, F32 volume)
{
- static pa_cvolume cvol;
- llpa_cvolume_set(&cvol, mSinkInputNumChannels[index],
- llpa_sw_volume_from_linear(volume));
-
- pa_context *c = mPAContext;
- uint32_t idx = index;
- const pa_cvolume *cvolumep = &cvol;
- pa_context_success_cb_t cb = nullptr; // okay as null
- void *userdata = nullptr; // okay as null
-
- pa_operation *op;
- if ((op = llpa_context_set_sink_input_volume(c, idx, cvolumep, cb, userdata)))
- llpa_operation_unref(op);
+ static pa_cvolume cvol;
+ llpa_cvolume_set(&cvol, mSinkInputNumChannels[index],
+ llpa_sw_volume_from_linear(volume));
+
+ pa_context *c = mPAContext;
+ uint32_t idx = index;
+ const pa_cvolume *cvolumep = &cvol;
+ pa_context_success_cb_t cb = nullptr; // okay as null
+ void *userdata = nullptr; // okay as null
+
+ pa_operation *op;
+ if ((op = llpa_context_set_sink_input_volume(c, idx, cvolumep, cb, userdata)))
+ llpa_operation_unref(op);
}
void callback_discovered_sinkinput(pa_context *context, const pa_sink_input_info *sii, int eol, void *userdata)
{
- VolumeCatcherPulseAudio *impl = dynamic_cast<VolumeCatcherPulseAudio*>((VolumeCatcherPulseAudio*)userdata);
- llassert(impl);
-
- if (0 == eol)
- {
- pa_proplist *proplist = sii->proplist;
- pid_t sinkpid = atoll(llpa_proplist_gets(proplist, PA_PROP_APPLICATION_PROCESS_ID));
-
- if (isPluginPid( sinkpid )) // does the discovered sinkinput belong to this process?
- {
- bool is_new = (impl->mSinkInputIndices.find(sii->index) == impl->mSinkInputIndices.end());
-
- impl->mSinkInputIndices.insert(sii->index);
- impl->mSinkInputNumChannels[sii->index] = sii->channel_map.channels;
-
- if (is_new)
- {
- // new!
- impl->update_index_volume(sii->index, impl->mDesiredVolume);
- }
- else
- {
- // seen it already, do nothing.
- }
- }
- }
+ VolumeCatcherPulseAudio *impl = dynamic_cast<VolumeCatcherPulseAudio*>((VolumeCatcherPulseAudio*)userdata);
+ llassert(impl);
+
+ if (0 == eol)
+ {
+ pa_proplist *proplist = sii->proplist;
+ pid_t sinkpid = atoll(llpa_proplist_gets(proplist, PA_PROP_APPLICATION_PROCESS_ID));
+
+ if (isPluginPid( sinkpid )) // does the discovered sinkinput belong to this process?
+ {
+ bool is_new = (impl->mSinkInputIndices.find(sii->index) == impl->mSinkInputIndices.end());
+
+ impl->mSinkInputIndices.insert(sii->index);
+ impl->mSinkInputNumChannels[sii->index] = sii->channel_map.channels;
+
+ if (is_new)
+ {
+ // new!
+ impl->update_index_volume(sii->index, impl->mDesiredVolume);
+ }
+ else
+ {
+ // seen it already, do nothing.
+ }
+ }
+ }
}
void callback_subscription_alert(pa_context *context, pa_subscription_event_type_t t, uint32_t index, void *userdata)
{
- VolumeCatcherPulseAudio *impl = dynamic_cast<VolumeCatcherPulseAudio*>((VolumeCatcherPulseAudio*)userdata);
- llassert(impl);
+ VolumeCatcherPulseAudio *impl = dynamic_cast<VolumeCatcherPulseAudio*>((VolumeCatcherPulseAudio*)userdata);
+ llassert(impl);
- switch (t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK)
- {
+ switch (t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK)
+ {
case PA_SUBSCRIPTION_EVENT_SINK_INPUT:
- if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE)
- {
- // forget this sinkinput, if we were caring about it
- impl->mSinkInputIndices.erase(index);
- impl->mSinkInputNumChannels.erase(index);
- }
- else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW)
- {
- // ask for more info about this new sinkinput
- pa_operation *op;
- if ((op = llpa_context_get_sink_input_info(impl->mPAContext, index, callback_discovered_sinkinput, impl)))
- {
- llpa_operation_unref(op);
- }
- }
- else
- {
- // property change on this sinkinput - we don't care.
- }
- break;
-
- default:;
- }
+ if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE)
+ {
+ // forget this sinkinput, if we were caring about it
+ impl->mSinkInputIndices.erase(index);
+ impl->mSinkInputNumChannels.erase(index);
+ }
+ else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW)
+ {
+ // ask for more info about this new sinkinput
+ pa_operation *op;
+ if ((op = llpa_context_get_sink_input_info(impl->mPAContext, index, callback_discovered_sinkinput, impl)))
+ {
+ llpa_operation_unref(op);
+ }
+ }
+ else
+ {
+ // property change on this sinkinput - we don't care.
+ }
+ break;
+
+ default:;
+ }
}
void callback_context_state(pa_context *context, void *userdata)
{
- VolumeCatcherPulseAudio *impl = dynamic_cast<VolumeCatcherPulseAudio*>((VolumeCatcherPulseAudio*)userdata);
- llassert(impl);
-
- switch (llpa_context_get_state(context))
- {
- case PA_CONTEXT_READY:
- impl->mConnected = true;
- impl->connected_okay();
- break;
- case PA_CONTEXT_TERMINATED:
- impl->mConnected = false;
- break;
- case PA_CONTEXT_FAILED:
- impl->mConnected = false;
- break;
- default:;
- }
+ VolumeCatcherPulseAudio *impl = dynamic_cast<VolumeCatcherPulseAudio*>((VolumeCatcherPulseAudio*)userdata);
+ llassert(impl);
+
+ switch (llpa_context_get_state(context))
+ {
+ case PA_CONTEXT_READY:
+ impl->mConnected = true;
+ impl->connected_okay();
+ break;
+ case PA_CONTEXT_TERMINATED:
+ impl->mConnected = false;
+ break;
+ case PA_CONTEXT_FAILED:
+ impl->mConnected = false;
+ break;
+ default:;
+ }
}