m-mixer-api: track monitorVolumes and allow modifying them
This only applies to non-device nodes, because monitorVolumes are not exposed on device Routes
This commit is contained in:
@@ -30,6 +30,7 @@ struct node_info {
|
|||||||
gint32 route_device;
|
gint32 route_device;
|
||||||
|
|
||||||
struct volume volume;
|
struct volume volume;
|
||||||
|
struct volume monitorVolume;
|
||||||
struct channel_map map;
|
struct channel_map map;
|
||||||
bool mute;
|
bool mute;
|
||||||
float svolume;
|
float svolume;
|
||||||
@@ -129,6 +130,7 @@ node_info_fill (struct node_info * info, WpSpaPod * props)
|
|||||||
{
|
{
|
||||||
g_autoptr (WpSpaPod) channelVolumes = NULL;
|
g_autoptr (WpSpaPod) channelVolumes = NULL;
|
||||||
g_autoptr (WpSpaPod) channelMap = NULL;
|
g_autoptr (WpSpaPod) channelMap = NULL;
|
||||||
|
g_autoptr (WpSpaPod) monitorVolumes = NULL;
|
||||||
|
|
||||||
if (!wp_spa_pod_get_object (props, NULL,
|
if (!wp_spa_pod_get_object (props, NULL,
|
||||||
"mute", "b", &info->mute,
|
"mute", "b", &info->mute,
|
||||||
@@ -146,6 +148,7 @@ node_info_fill (struct node_info * info, WpSpaPod * props)
|
|||||||
"volumeBase", "?f", &info->base,
|
"volumeBase", "?f", &info->base,
|
||||||
"volumeStep", "?f", &info->step,
|
"volumeStep", "?f", &info->step,
|
||||||
"volume", "?f", &info->svolume,
|
"volume", "?f", &info->svolume,
|
||||||
|
"monitorVolumes", "?P", &monitorVolumes,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
info->volume.channels = spa_pod_copy_array (
|
info->volume.channels = spa_pod_copy_array (
|
||||||
@@ -157,6 +160,11 @@ node_info_fill (struct node_info * info, WpSpaPod * props)
|
|||||||
wp_spa_pod_get_spa_pod (channelMap), SPA_TYPE_Id,
|
wp_spa_pod_get_spa_pod (channelMap), SPA_TYPE_Id,
|
||||||
info->map.map, SPA_AUDIO_MAX_CHANNELS);
|
info->map.map, SPA_AUDIO_MAX_CHANNELS);
|
||||||
|
|
||||||
|
if (monitorVolumes)
|
||||||
|
info->monitorVolume.channels = spa_pod_copy_array (
|
||||||
|
wp_spa_pod_get_spa_pod (monitorVolumes), SPA_TYPE_Float,
|
||||||
|
info->monitorVolume.values, SPA_AUDIO_MAX_CHANNELS);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -383,6 +391,7 @@ wp_mixer_api_set_volume (WpMixerApi * self, guint32 id, GVariant * vvolume)
|
|||||||
struct node_info *info = self->node_infos ?
|
struct node_info *info = self->node_infos ?
|
||||||
g_hash_table_lookup (self->node_infos, GUINT_TO_POINTER (id)) : NULL;
|
g_hash_table_lookup (self->node_infos, GUINT_TO_POINTER (id)) : NULL;
|
||||||
struct volume new_volume = {0};
|
struct volume new_volume = {0};
|
||||||
|
struct volume new_monVolume = {0};
|
||||||
gint mute = -1;
|
gint mute = -1;
|
||||||
WpSpaIdTable t_audioChannel =
|
WpSpaIdTable t_audioChannel =
|
||||||
wp_spa_id_table_from_name ("Spa:Enum:AudioChannel");
|
wp_spa_id_table_from_name ("Spa:Enum:AudioChannel");
|
||||||
@@ -410,9 +419,16 @@ wp_mixer_api_set_volume (WpMixerApi * self, guint32 id, GVariant * vvolume)
|
|||||||
new_volume.values[i] = volume_to_linear (val, self->scale);
|
new_volume.values[i] = volume_to_linear (val, self->scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (g_variant_lookup (vvolume, "monitorVolume", "d", &val)) {
|
||||||
|
new_monVolume = info->monitorVolume;
|
||||||
|
for (uint i = 0; i < new_monVolume.channels; i++)
|
||||||
|
new_monVolume.values[i] = volume_to_linear (val, self->scale);
|
||||||
|
}
|
||||||
|
|
||||||
if (g_variant_lookup (vvolume, "channelVolumes", "a{sv}", &iter)) {
|
if (g_variant_lookup (vvolume, "channelVolumes", "a{sv}", &iter)) {
|
||||||
/* keep the existing volume values for unspecified channels */
|
/* keep the existing volume values for unspecified channels */
|
||||||
new_volume = info->volume;
|
new_volume = info->volume;
|
||||||
|
new_monVolume = info->monitorVolume;
|
||||||
|
|
||||||
while (g_variant_iter_loop (&iter, "{&sv}", &idx_str, &v)) {
|
while (g_variant_iter_loop (&iter, "{&sv}", &idx_str, &v)) {
|
||||||
guint index = atoi (idx_str);
|
guint index = atoi (idx_str);
|
||||||
@@ -442,6 +458,9 @@ wp_mixer_api_set_volume (WpMixerApi * self, guint32 id, GVariant * vvolume)
|
|||||||
if (g_variant_lookup (v, "volume", "d", &val)) {
|
if (g_variant_lookup (v, "volume", "d", &val)) {
|
||||||
new_volume.values[index] = volume_to_linear (val, self->scale);
|
new_volume.values[index] = volume_to_linear (val, self->scale);
|
||||||
}
|
}
|
||||||
|
if (g_variant_lookup (v, "monitorVolume", "d", &val)) {
|
||||||
|
new_monVolume.values[index] = volume_to_linear (val, self->scale);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -457,6 +476,10 @@ wp_mixer_api_set_volume (WpMixerApi * self, guint32 id, GVariant * vvolume)
|
|||||||
wp_spa_pod_builder_add (b, "channelVolumes", "a",
|
wp_spa_pod_builder_add (b, "channelVolumes", "a",
|
||||||
sizeof(float), SPA_TYPE_Float,
|
sizeof(float), SPA_TYPE_Float,
|
||||||
new_volume.channels, new_volume.values, NULL);
|
new_volume.channels, new_volume.values, NULL);
|
||||||
|
if (new_monVolume.channels > 0)
|
||||||
|
wp_spa_pod_builder_add (b, "monitorVolumes", "a",
|
||||||
|
sizeof(float), SPA_TYPE_Float,
|
||||||
|
new_monVolume.channels, new_monVolume.values, NULL);
|
||||||
if (mute != -1)
|
if (mute != -1)
|
||||||
wp_spa_pod_builder_add (b, "mute", "b", (mute == TRUE), NULL);
|
wp_spa_pod_builder_add (b, "mute", "b", (mute == TRUE), NULL);
|
||||||
|
|
||||||
@@ -509,6 +532,10 @@ wp_mixer_api_get_volume (WpMixerApi * self, guint32 id)
|
|||||||
g_variant_builder_add (&b, "{sv}", "volume", g_variant_new_double (
|
g_variant_builder_add (&b, "{sv}", "volume", g_variant_new_double (
|
||||||
volume_from_linear ((info->volume.channels > 0) ?
|
volume_from_linear ((info->volume.channels > 0) ?
|
||||||
info->volume.values[0] : info->svolume, self->scale)));
|
info->volume.values[0] : info->svolume, self->scale)));
|
||||||
|
if (info->monitorVolume.channels > 0) {
|
||||||
|
g_variant_builder_add (&b, "{sv}", "monitorVolume", g_variant_new_double (
|
||||||
|
volume_from_linear (info->monitorVolume.values[0], self->scale)));
|
||||||
|
}
|
||||||
|
|
||||||
for (guint i = 0; i < info->volume.channels; i++) {
|
for (guint i = 0; i < info->volume.channels; i++) {
|
||||||
gchar index_str[10];
|
gchar index_str[10];
|
||||||
@@ -529,6 +556,12 @@ wp_mixer_api_get_volume (WpMixerApi * self, guint32 id)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (i < info->monitorVolume.channels) {
|
||||||
|
g_variant_builder_add (&b_vol_nested, "{sv}",
|
||||||
|
"monitorVolume", g_variant_new_double (
|
||||||
|
volume_from_linear (info->monitorVolume.values[i], self->scale)));
|
||||||
|
}
|
||||||
|
|
||||||
g_snprintf (index_str, 10, "%u", i);
|
g_snprintf (index_str, 10, "%u", i);
|
||||||
g_variant_builder_add (&b_vol, "{sv}", index_str,
|
g_variant_builder_add (&b_vol, "{sv}", index_str,
|
||||||
g_variant_builder_end (&b_vol_nested));
|
g_variant_builder_end (&b_vol_nested));
|
||||||
|
Reference in New Issue
Block a user