Update the gain widget to support updating direct monitor mix controls
The 4th Gen Solo and 2i2 have controls to set custom Mix A/B gains when Direct Monitor is enabled. Update those controls when the Mix A/B gains are updated so that they are remembered.
This commit is contained in:
@@ -2,10 +2,13 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#include "gtkdial.h"
|
||||
#include "stringhelper.h"
|
||||
#include "widget-gain.h"
|
||||
|
||||
struct gain {
|
||||
struct alsa_elem *elem;
|
||||
struct alsa_elem *direct_monitor_elem;
|
||||
struct alsa_elem *monitor_mix_elem[2];
|
||||
GtkWidget *vbox;
|
||||
GtkWidget *dial;
|
||||
GtkWidget *label;
|
||||
@@ -15,8 +18,28 @@ struct gain {
|
||||
|
||||
static void gain_changed(GtkWidget *widget, struct gain *data) {
|
||||
int value = gtk_dial_get_value(GTK_DIAL(data->dial));
|
||||
|
||||
alsa_set_elem_value(data->elem, value);
|
||||
|
||||
// check if there is a corresponding Direct Monitor Mix control to
|
||||
// update as well
|
||||
|
||||
// Direct Monitor control?
|
||||
if (!data->direct_monitor_elem)
|
||||
return;
|
||||
|
||||
// Direct Monitor enabled?
|
||||
int direct_monitor = alsa_get_elem_value(data->direct_monitor_elem);
|
||||
|
||||
if (!direct_monitor)
|
||||
return;
|
||||
|
||||
// Get the corresponding Mix control
|
||||
struct alsa_elem *monitor_mix = data->monitor_mix_elem[direct_monitor - 1];
|
||||
if (!monitor_mix)
|
||||
return;
|
||||
|
||||
// Update it
|
||||
alsa_set_elem_value(monitor_mix, value);
|
||||
}
|
||||
|
||||
static void gain_updated(
|
||||
@@ -56,6 +79,70 @@ static void gain_updated(
|
||||
gtk_label_set_text(GTK_LABEL(data->label), s);
|
||||
}
|
||||
|
||||
// 4th Gen Solo and 2i2 have Mix & Direct Monitor controls which
|
||||
// interact. If direct monitor is enabled and the Mix A/B controls are
|
||||
// changed, then the Monitor Mix Playback Volume controls are changed
|
||||
// too so that the mix settings are restored when direct monitor is
|
||||
// later enabled again.
|
||||
static void find_direct_monitor_controls(struct gain *data) {
|
||||
struct alsa_elem *elem = data->elem;
|
||||
GArray *elems = elem->card->elems;
|
||||
|
||||
// Card has no direct monitor control?
|
||||
struct alsa_elem *direct_monitor_elem = get_elem_by_prefix(
|
||||
elems,
|
||||
"Direct Monitor Playback"
|
||||
);
|
||||
if (!direct_monitor_elem)
|
||||
return;
|
||||
|
||||
// Card has no mixer?
|
||||
if (strncmp(elem->name, "Mix ", 4) != 0 ||
|
||||
!strstr(elem->name, "Playback Volume"))
|
||||
return;
|
||||
|
||||
char mix_letter = elem->name[4];
|
||||
int input_num = get_num_from_string(elem->name);
|
||||
|
||||
// Find the Monitor Mix control for the 4th Gen Solo
|
||||
if (strstr(direct_monitor_elem->name, "Switch")) {
|
||||
char s[80];
|
||||
sprintf(
|
||||
s,
|
||||
"Monitor Mix %c Input %02d Playback Volume",
|
||||
mix_letter, input_num
|
||||
);
|
||||
|
||||
struct alsa_elem *monitor_mix_elem = get_elem_by_name(elems, s);
|
||||
if (!monitor_mix_elem)
|
||||
return;
|
||||
|
||||
data->direct_monitor_elem = direct_monitor_elem;
|
||||
data->monitor_mix_elem[0] = monitor_mix_elem;
|
||||
|
||||
// Find the Monitor Mix controls for the 4th Gen 2i2
|
||||
} else if (strstr(direct_monitor_elem->name, "Enum")) {
|
||||
for (int i = 0; i <= 1; i++) {
|
||||
char s[80];
|
||||
sprintf(
|
||||
s,
|
||||
"Monitor %d Mix %c Input %02d Playback Volume",
|
||||
i + 1, mix_letter, input_num
|
||||
);
|
||||
|
||||
struct alsa_elem *monitor_mix_elem = get_elem_by_name(elems, s);
|
||||
if (!monitor_mix_elem)
|
||||
return;
|
||||
|
||||
data->direct_monitor_elem = direct_monitor_elem;
|
||||
data->monitor_mix_elem[i] = monitor_mix_elem;
|
||||
}
|
||||
|
||||
} else {
|
||||
fprintf(stderr, "Couldn't find direct monitor mix control\n");
|
||||
}
|
||||
}
|
||||
|
||||
//GList *make_gain_alsa_elem(struct alsa_elem *elem) {
|
||||
GtkWidget *make_gain_alsa_elem(
|
||||
struct alsa_elem *elem,
|
||||
@@ -63,7 +150,7 @@ GtkWidget *make_gain_alsa_elem(
|
||||
int widget_taper,
|
||||
int can_control
|
||||
) {
|
||||
struct gain *data = g_malloc(sizeof(struct gain));
|
||||
struct gain *data = calloc(1, sizeof(struct gain));
|
||||
data->elem = elem;
|
||||
data->vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
|
||||
gtk_widget_set_hexpand(data->vbox, TRUE);
|
||||
@@ -110,6 +197,8 @@ GtkWidget *make_gain_alsa_elem(
|
||||
|
||||
data->zero_is_off = zero_is_off;
|
||||
|
||||
find_direct_monitor_controls(data);
|
||||
|
||||
g_signal_connect(
|
||||
data->dial, "value-changed", G_CALLBACK(gain_changed), data
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user