Add support for routing the Gen 4 DSP I/O

This commit is contained in:
Geoffrey D. Bennett
2023-11-30 00:43:09 +10:30
parent dfa40c79b0
commit 658f946202
4 changed files with 96 additions and 28 deletions

View File

@@ -11,6 +11,7 @@
const char *port_category_names[PC_COUNT] = { const char *port_category_names[PC_COUNT] = {
"Hardware Outputs", "Hardware Outputs",
"Mixer Inputs", "Mixer Inputs",
"DSP Inputs",
"PCM Inputs" "PCM Inputs"
}; };

View File

@@ -28,11 +28,14 @@ enum {
// Mixer inputs/outputs // Mixer inputs/outputs
PC_MIX = 1, PC_MIX = 1,
// DSP inputs/outputs
PC_DSP = 2,
// PCM inputs/outputs // PCM inputs/outputs
PC_PCM = 2, PC_PCM = 3,
// number of port categories // number of port categories
PC_COUNT = 3 PC_COUNT = 4
}; };
// names for the port categories // names for the port categories
@@ -56,7 +59,7 @@ struct routing_src {
// the enum id of the alsa item // the enum id of the alsa item
int id; int id;
// PC_MIX, PC_PCM, or PC_HW // PC_DSP, PC_MIX, PC_PCM, or PC_HW
int port_category; int port_category;
// 0-based count within port_category // 0-based count within port_category
@@ -79,7 +82,7 @@ struct routing_src {
// entry in alsa_card routing_snks (routing sinks) array for alsa // entry in alsa_card routing_snks (routing sinks) array for alsa
// elements that are routing sinks like Analogue Output 01 Playback // elements that are routing sinks like Analogue Output 01 Playback
// Enum // Enum
// port_category is set to PC_MIX, PC_PCM, PC_HW // port_category is set to PC_DSP, PC_MIX, PC_PCM, PC_HW
// port_num is a count (0-based) within that category // port_num is a count (0-based) within that category
struct routing_snk { struct routing_snk {
@@ -89,7 +92,7 @@ struct routing_snk {
// pointer back to the element this entry is associated with // pointer back to the element this entry is associated with
struct alsa_elem *elem; struct alsa_elem *elem;
// PC_MIX, PC_PCM, or PC_HW // PC_DSP, PC_MIX, PC_PCM, or PC_HW
int port_category; int port_category;
// 0-based count within port_category // 0-based count within port_category
@@ -164,6 +167,8 @@ struct alsa_card {
GtkWidget *routing_hw_out_grid; GtkWidget *routing_hw_out_grid;
GtkWidget *routing_pcm_in_grid; GtkWidget *routing_pcm_in_grid;
GtkWidget *routing_pcm_out_grid; GtkWidget *routing_pcm_out_grid;
GtkWidget *routing_dsp_in_grid;
GtkWidget *routing_dsp_out_grid;
GtkWidget *routing_mixer_in_grid; GtkWidget *routing_mixer_in_grid;
GtkWidget *routing_mixer_out_grid; GtkWidget *routing_mixer_out_grid;
GtkWidget *meters[MAX_METERS]; GtkWidget *meters[MAX_METERS];

View File

@@ -10,6 +10,10 @@ static const double dash_dotted[] = { 1, 10 };
// dash when dragging and not connected // dash when dragging and not connected
static const double dash[] = { 4 }; static const double dash[] = { 4 };
// is a port category a mixer or DSP port, therefore at the
// top/bottom?
#define IS_MIXER(x) ((x) == PC_MIX || (x) == PC_DSP)
static void choose_line_colour( static void choose_line_colour(
struct routing_src *r_src, struct routing_src *r_src,
struct routing_snk *r_snk, struct routing_snk *r_snk,
@@ -53,8 +57,8 @@ static void choose_line_colour(
} }
// mix <-> non-mix, add blue // mix <-> non-mix, add blue
if ((r_src->port_category == PC_MIX) != if (IS_MIXER(r_src->port_category) !=
(r_snk->port_category == PC_MIX)) { IS_MIXER(r_snk->port_category)) {
*b = 0.5; *b = 0.5;
} }
@@ -166,10 +170,10 @@ static void draw_connection(
cairo_t *cr, cairo_t *cr,
double x1, double x1,
double y1, double y1,
int src_is_mixer, int src_port_category,
double x2, double x2,
double y2, double y2,
int snk_is_mixer, int snk_port_category,
double r, double r,
double g, double g,
double b, double b,
@@ -177,6 +181,9 @@ static void draw_connection(
) { ) {
double x3 = x1, y3 = y1, x4 = x2, y4 = y2; double x3 = x1, y3 = y1, x4 = x2, y4 = y2;
int src_is_mixer = IS_MIXER(src_port_category);
int snk_is_mixer = IS_MIXER(snk_port_category);
// vertical/horizontal? // vertical/horizontal?
if (src_is_mixer == snk_is_mixer) { if (src_is_mixer == snk_is_mixer) {
double f1 = 0.3; double f1 = 0.3;
@@ -241,7 +248,7 @@ static void get_src_center(
double *y double *y
) { ) {
get_widget_center(r_src->widget2, parent, x, y); get_widget_center(r_src->widget2, parent, x, y);
if (r_src->port_category == PC_MIX) if (IS_MIXER(r_src->port_category))
(*y)++; (*y)++;
} }
@@ -252,7 +259,7 @@ static void get_snk_center(
double *y double *y
) { ) {
get_widget_center(r_snk->elem->widget2, parent, x, y); get_widget_center(r_snk->elem->widget2, parent, x, y);
if (r_snk->port_category == PC_MIX) if (IS_MIXER(r_snk->port_category))
(*y)++; (*y)++;
} }
@@ -314,8 +321,8 @@ void draw_routing_lines(
// draw the connection // draw the connection
draw_connection( draw_connection(
cr, cr,
x1, y1, r_src->port_category == PC_MIX, x1, y1, r_src->port_category,
x2, y2, r_snk->port_category == PC_MIX, x2, y2, r_snk->port_category,
r, g, b, 2 r, g, b, 2
); );
} }
@@ -376,8 +383,8 @@ void draw_drag_line(
if (card->src_drag && card->snk_drag) { if (card->src_drag && card->snk_drag) {
draw_connection( draw_connection(
cr, cr,
x1, y1, card->src_drag->port_category == PC_MIX, x1, y1, card->src_drag->port_category,
x2, y2, card->snk_drag->port_category == PC_MIX, x2, y2, card->snk_drag->port_category,
0, 0, 0, 2 0, 0, 0, 2
); );

View File

@@ -30,6 +30,8 @@ static void get_routing_srcs(struct alsa_card *card) {
if (strncmp(name, "Mix", 3) == 0) if (strncmp(name, "Mix", 3) == 0)
r->port_category = PC_MIX; r->port_category = PC_MIX;
else if (strncmp(name, "DSP", 3) == 0)
r->port_category = PC_DSP;
else if (strncmp(name, "PCM", 3) == 0) else if (strncmp(name, "PCM", 3) == 0)
r->port_category = PC_PCM; r->port_category = PC_PCM;
else else
@@ -93,6 +95,8 @@ static void get_routing_snks(struct alsa_card *card) {
r->elem = elem; r->elem = elem;
if (strncmp(elem->name, "Mixer Input", 11) == 0) { if (strncmp(elem->name, "Mixer Input", 11) == 0) {
r->port_category = PC_MIX; r->port_category = PC_MIX;
} else if (strncmp(elem->name, "DSP Input", 9) == 0) {
r->port_category = PC_DSP;
} else if (strncmp(elem->name, "PCM", 3) == 0) { } else if (strncmp(elem->name, "PCM", 3) == 0) {
r->port_category = PC_PCM; r->port_category = PC_PCM;
} else if (strstr(elem->name, "Playback Enum")) { } else if (strstr(elem->name, "Playback Enum")) {
@@ -287,6 +291,8 @@ static GtkWidget *create_routing_group_grid(
static void create_routing_grid(struct alsa_card *card) { static void create_routing_grid(struct alsa_card *card) {
GtkGrid *routing_grid = GTK_GRID(card->routing_grid = gtk_grid_new()); GtkGrid *routing_grid = GTK_GRID(card->routing_grid = gtk_grid_new());
int has_dsp = !!card->routing_in_count[PC_DSP];
gtk_widget_set_halign(card->routing_grid, GTK_ALIGN_CENTER); gtk_widget_set_halign(card->routing_grid, GTK_ALIGN_CENTER);
gtk_widget_set_valign(card->routing_grid, GTK_ALIGN_CENTER); gtk_widget_set_valign(card->routing_grid, GTK_ALIGN_CENTER);
@@ -311,6 +317,16 @@ static void create_routing_grid(struct alsa_card *card) {
card, "routing_hw_out_grid", "Hardware Outputs", card, "routing_hw_out_grid", "Hardware Outputs",
GTK_ORIENTATION_VERTICAL, GTK_ALIGN_START GTK_ORIENTATION_VERTICAL, GTK_ALIGN_START
); );
if (has_dsp) {
card->routing_dsp_in_grid = create_routing_group_grid(
card, "routing_dsp_in_grid", "DSP\nInputs",
GTK_ORIENTATION_HORIZONTAL, GTK_ALIGN_CENTER
);
card->routing_dsp_out_grid = create_routing_group_grid(
card, "routing_dsp_out_grid", "DSP\nOutputs",
GTK_ORIENTATION_HORIZONTAL, GTK_ALIGN_CENTER
);
}
card->routing_mixer_in_grid = create_routing_group_grid( card->routing_mixer_in_grid = create_routing_group_grid(
card, "routing_mixer_in_grid", "Mixer\nInputs", card, "routing_mixer_in_grid", "Mixer\nInputs",
GTK_ORIENTATION_HORIZONTAL, GTK_ALIGN_CENTER GTK_ORIENTATION_HORIZONTAL, GTK_ALIGN_CENTER
@@ -321,34 +337,47 @@ static void create_routing_grid(struct alsa_card *card) {
GTK_ORIENTATION_HORIZONTAL, GTK_ALIGN_CENTER GTK_ORIENTATION_HORIZONTAL, GTK_ALIGN_CENTER
); );
int left_col_num = 0;
int dsp_col_num = has_dsp ? 1 : 0;
int mix_col_num = dsp_col_num + 1;
int right_col_num = mix_col_num + 1;
gtk_grid_attach( gtk_grid_attach(
routing_grid, card->routing_hw_in_grid, 0, 1, 1, 1 routing_grid, card->routing_hw_in_grid, left_col_num, 1, 1, 1
); );
gtk_grid_attach( gtk_grid_attach(
routing_grid, card->routing_pcm_in_grid, 0, 2, 1, 1 routing_grid, card->routing_pcm_in_grid, left_col_num, 2, 1, 1
); );
gtk_grid_attach( gtk_grid_attach(
routing_grid, card->routing_pcm_out_grid, 2, 1, 1, 1 routing_grid, card->routing_pcm_out_grid, right_col_num, 1, 1, 1
); );
gtk_grid_attach( gtk_grid_attach(
routing_grid, card->routing_hw_out_grid, 2, 2, 1, 1 routing_grid, card->routing_hw_out_grid, right_col_num, 2, 1, 1
);
if (has_dsp) {
gtk_grid_attach(
routing_grid, card->routing_dsp_in_grid, dsp_col_num, 0, 1, 1
); );
gtk_grid_attach( gtk_grid_attach(
routing_grid, card->routing_mixer_in_grid, 1, 0, 1, 1 routing_grid, card->routing_dsp_out_grid, dsp_col_num, 3, 1, 1
);
}
gtk_grid_attach(
routing_grid, card->routing_mixer_in_grid, mix_col_num, 0, 1, 1
); );
gtk_grid_attach( gtk_grid_attach(
routing_grid, card->routing_mixer_out_grid, 1, 3, 1, 1 routing_grid, card->routing_mixer_out_grid, mix_col_num, 3, 1, 1
); );
gtk_widget_set_margin(card->routing_grid, 10); gtk_widget_set_margin(card->routing_grid, 10);
gtk_grid_set_spacing(routing_grid, 10); gtk_grid_set_spacing(routing_grid, 10);
GtkWidget *src_label = gtk_label_new("\nSources →"); GtkWidget *src_label = gtk_label_new("\nSources →");
gtk_label_set_justify(GTK_LABEL(src_label), GTK_JUSTIFY_CENTER); gtk_label_set_justify(GTK_LABEL(src_label), GTK_JUSTIFY_CENTER);
gtk_grid_attach(routing_grid, src_label, 0, 3, 1, 1); gtk_grid_attach(routing_grid, src_label, left_col_num, 3, 1, 1);
GtkWidget *snk_label = gtk_label_new("← Sinks\n"); GtkWidget *snk_label = gtk_label_new("← Sinks\n");
gtk_label_set_justify(GTK_LABEL(snk_label), GTK_JUSTIFY_CENTER); gtk_label_set_justify(GTK_LABEL(snk_label), GTK_JUSTIFY_CENTER);
gtk_grid_attach(routing_grid, snk_label, 2, 0, 1, 1); gtk_grid_attach(routing_grid, snk_label, right_col_num, 0, 1, 1);
} }
static GtkWidget *make_socket_widget(void) { static GtkWidget *make_socket_widget(void) {
@@ -759,9 +788,22 @@ static void make_routing_alsa_elem(struct routing_snk *r_snk) {
struct alsa_elem *elem = r_snk->elem; struct alsa_elem *elem = r_snk->elem;
struct alsa_card *card = elem->card; struct alsa_card *card = elem->card;
// "Mixer Input X Capture Enum" controls (Mixer Inputs) go along // "DSP Input X Capture Enum" controls (DSP Inputs) go along
// the top, in card->routing_mixer_in_grid // the top, in card->routing_mixer_in_grid
if (r_snk->port_category == PC_MIX) { if (r_snk->port_category == PC_DSP) {
char name[10];
snprintf(name, 10, "%d", elem->lr_num);
make_snk_routing_widget(r_snk, name, GTK_ORIENTATION_VERTICAL);
gtk_grid_attach(
GTK_GRID(card->routing_dsp_in_grid), elem->widget,
r_snk->port_num + 1, 0, 1, 1
);
// "Mixer Input X Capture Enum" controls (Mixer Inputs) go along
// the top, in card->routing_mixer_in_grid after the DSP Inputs
} else if (r_snk->port_category == PC_MIX) {
char name[10]; char name[10];
@@ -840,7 +882,20 @@ static void add_routing_widgets(
card->routing_srcs, struct routing_src, i card->routing_srcs, struct routing_src, i
); );
if (r_src->port_category == PC_MIX) { if (r_src->port_category == PC_DSP) {
// r_src->name is "DSP X"
// +4 to skip "DSP "
make_src_routing_widget(
card, r_src, r_src->name + 4, GTK_ORIENTATION_VERTICAL
);
gtk_grid_attach(
GTK_GRID(card->routing_dsp_out_grid), r_src->widget,
r_src->port_num + 1, 0, 1, 1
);
} else if (r_src->port_category == PC_MIX) {
// r_src->name is "Mix X"
// +4 to skip "Mix "
make_src_routing_widget( make_src_routing_widget(
card, r_src, r_src->name + 4, GTK_ORIENTATION_VERTICAL card, r_src, r_src->name + 4, GTK_ORIENTATION_VERTICAL
); );