Add node volume
This commit is contained in:
parent
fa67dd3708
commit
e649dea9c1
3 changed files with 157 additions and 0 deletions
|
|
@ -14,6 +14,8 @@
|
|||
#include <pipewire/extensions/metadata.h>
|
||||
|
||||
#include <spa/param/audio/format-utils.h>
|
||||
#include <spa/param/props.h>
|
||||
#include <spa/pod/builder.h>
|
||||
#include <spa/utils/defs.h>
|
||||
|
||||
#include <spa/utils/result.h>
|
||||
|
|
@ -277,6 +279,8 @@ struct Client::Impl {
|
|||
std::unordered_map<uint32_t, std::unique_ptr<StreamData>> virtual_streams;
|
||||
std::unordered_map<uint32_t, std::unique_ptr<LinkProxy>> link_proxies;
|
||||
|
||||
std::unordered_map<uint32_t, VolumeState> volume_states;
|
||||
|
||||
uint32_t next_rule_id = 1;
|
||||
std::unordered_map<uint32_t, RouteRule> route_rules;
|
||||
std::vector<PendingAutoLink> pending_auto_links;
|
||||
|
|
@ -1216,6 +1220,64 @@ Status Client::RemoveNode(NodeId node) {
|
|||
return Status::Ok();
|
||||
}
|
||||
|
||||
Status Client::SetNodeVolume(NodeId node, float volume, bool mute) {
|
||||
Status status = impl_->EnsureConnected();
|
||||
if (!status.ok()) {
|
||||
return status;
|
||||
}
|
||||
if (node.value == 0) {
|
||||
return Status::Error(StatusCode::kInvalidArgument, "invalid node id");
|
||||
}
|
||||
|
||||
volume = std::clamp(volume, 0.0f, 1.5f);
|
||||
|
||||
pw_thread_loop_lock(impl_->thread_loop);
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(impl_->cache_mutex);
|
||||
if (impl_->nodes.find(node.value) == impl_->nodes.end()) {
|
||||
pw_thread_loop_unlock(impl_->thread_loop);
|
||||
return Status::Error(StatusCode::kNotFound, "node not found");
|
||||
}
|
||||
}
|
||||
|
||||
auto* proxy = static_cast<pw_node*>(
|
||||
pw_registry_bind(impl_->registry, node.value,
|
||||
PW_TYPE_INTERFACE_Node, PW_VERSION_NODE, 0));
|
||||
if (!proxy) {
|
||||
pw_thread_loop_unlock(impl_->thread_loop);
|
||||
return Status::Error(StatusCode::kInternal, "failed to bind node proxy");
|
||||
}
|
||||
|
||||
uint8_t buffer[128];
|
||||
spa_pod_builder builder = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer));
|
||||
auto* param = reinterpret_cast<const spa_pod*>(spa_pod_builder_add_object(
|
||||
&builder,
|
||||
SPA_TYPE_OBJECT_Props, SPA_PARAM_Props,
|
||||
SPA_PROP_volume, SPA_POD_Float(volume),
|
||||
SPA_PROP_mute, SPA_POD_Bool(mute)));
|
||||
|
||||
pw_node_set_param(proxy, SPA_PARAM_Props, 0, param);
|
||||
pw_proxy_destroy(reinterpret_cast<pw_proxy*>(proxy));
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(impl_->cache_mutex);
|
||||
impl_->volume_states[node.value] = VolumeState{volume, mute};
|
||||
}
|
||||
|
||||
pw_thread_loop_unlock(impl_->thread_loop);
|
||||
return Status::Ok();
|
||||
}
|
||||
|
||||
Result<VolumeState> Client::GetNodeVolume(NodeId node) const {
|
||||
std::lock_guard<std::mutex> lock(impl_->cache_mutex);
|
||||
auto it = impl_->volume_states.find(node.value);
|
||||
if (it == impl_->volume_states.end()) {
|
||||
return {Status::Ok(), VolumeState{}};
|
||||
}
|
||||
return {Status::Ok(), it->second};
|
||||
}
|
||||
|
||||
Result<Link> Client::CreateLink(PortId output, PortId input, const LinkOptions& options) {
|
||||
Status status = impl_->EnsureConnected();
|
||||
if (!status.ok()) {
|
||||
|
|
@ -1719,6 +1781,30 @@ size_t Client::Test_GetPendingAutoLinkCount() const {
|
|||
std::lock_guard<std::mutex> lock(impl_->cache_mutex);
|
||||
return impl_->pending_auto_links.size();
|
||||
}
|
||||
|
||||
Status Client::Test_SetNodeVolume(NodeId node, float volume, bool mute) {
|
||||
if (!impl_) {
|
||||
return Status::Error(StatusCode::kUnavailable, "no impl");
|
||||
}
|
||||
std::lock_guard<std::mutex> lock(impl_->cache_mutex);
|
||||
if (impl_->nodes.find(node.value) == impl_->nodes.end()) {
|
||||
return Status::Error(StatusCode::kNotFound, "node not found");
|
||||
}
|
||||
impl_->volume_states[node.value] = VolumeState{std::clamp(volume, 0.0f, 1.5f), mute};
|
||||
return Status::Ok();
|
||||
}
|
||||
|
||||
Result<VolumeState> Client::Test_GetNodeVolume(NodeId node) const {
|
||||
if (!impl_) {
|
||||
return {Status::Error(StatusCode::kUnavailable, "no impl"), {}};
|
||||
}
|
||||
std::lock_guard<std::mutex> lock(impl_->cache_mutex);
|
||||
auto it = impl_->volume_states.find(node.value);
|
||||
if (it == impl_->volume_states.end()) {
|
||||
return {Status::Ok(), VolumeState{}};
|
||||
}
|
||||
return {Status::Ok(), it->second};
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace warppipe
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue