From 658f9462020e2afebe8c32bdf9650aed5f97ff5c Mon Sep 17 00:00:00 2001 From: "Geoffrey D. Bennett" Date: Thu, 30 Nov 2023 00:43:09 +1030 Subject: [PATCH] Add support for routing the Gen 4 DSP I/O --- src/alsa.c | 1 + src/alsa.h | 15 +++++--- src/routing-lines.c | 27 +++++++++------ src/window-routing.c | 81 +++++++++++++++++++++++++++++++++++++------- 4 files changed, 96 insertions(+), 28 deletions(-) diff --git a/src/alsa.c b/src/alsa.c index 5133dac..7ea8ac6 100644 --- a/src/alsa.c +++ b/src/alsa.c @@ -11,6 +11,7 @@ const char *port_category_names[PC_COUNT] = { "Hardware Outputs", "Mixer Inputs", + "DSP Inputs", "PCM Inputs" }; diff --git a/src/alsa.h b/src/alsa.h index 6c46145..bd08d4d 100644 --- a/src/alsa.h +++ b/src/alsa.h @@ -28,11 +28,14 @@ enum { // Mixer inputs/outputs PC_MIX = 1, + // DSP inputs/outputs + PC_DSP = 2, + // PCM inputs/outputs - PC_PCM = 2, + PC_PCM = 3, // number of port categories - PC_COUNT = 3 + PC_COUNT = 4 }; // names for the port categories @@ -56,7 +59,7 @@ struct routing_src { // the enum id of the alsa item int id; - // PC_MIX, PC_PCM, or PC_HW + // PC_DSP, PC_MIX, PC_PCM, or PC_HW int 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 // elements that are routing sinks like Analogue Output 01 Playback // 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 struct routing_snk { @@ -89,7 +92,7 @@ struct routing_snk { // pointer back to the element this entry is associated with struct alsa_elem *elem; - // PC_MIX, PC_PCM, or PC_HW + // PC_DSP, PC_MIX, PC_PCM, or PC_HW int port_category; // 0-based count within port_category @@ -164,6 +167,8 @@ struct alsa_card { GtkWidget *routing_hw_out_grid; GtkWidget *routing_pcm_in_grid; GtkWidget *routing_pcm_out_grid; + GtkWidget *routing_dsp_in_grid; + GtkWidget *routing_dsp_out_grid; GtkWidget *routing_mixer_in_grid; GtkWidget *routing_mixer_out_grid; GtkWidget *meters[MAX_METERS]; diff --git a/src/routing-lines.c b/src/routing-lines.c index bb0b780..502d94e 100644 --- a/src/routing-lines.c +++ b/src/routing-lines.c @@ -10,6 +10,10 @@ static const double dash_dotted[] = { 1, 10 }; // dash when dragging and not connected 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( struct routing_src *r_src, struct routing_snk *r_snk, @@ -53,8 +57,8 @@ static void choose_line_colour( } // mix <-> non-mix, add blue - if ((r_src->port_category == PC_MIX) != - (r_snk->port_category == PC_MIX)) { + if (IS_MIXER(r_src->port_category) != + IS_MIXER(r_snk->port_category)) { *b = 0.5; } @@ -166,10 +170,10 @@ static void draw_connection( cairo_t *cr, double x1, double y1, - int src_is_mixer, + int src_port_category, double x2, double y2, - int snk_is_mixer, + int snk_port_category, double r, double g, double b, @@ -177,6 +181,9 @@ static void draw_connection( ) { 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? if (src_is_mixer == snk_is_mixer) { double f1 = 0.3; @@ -241,7 +248,7 @@ static void get_src_center( double *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)++; } @@ -252,7 +259,7 @@ static void get_snk_center( double *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)++; } @@ -314,8 +321,8 @@ void draw_routing_lines( // draw the connection draw_connection( cr, - x1, y1, r_src->port_category == PC_MIX, - x2, y2, r_snk->port_category == PC_MIX, + x1, y1, r_src->port_category, + x2, y2, r_snk->port_category, r, g, b, 2 ); } @@ -376,8 +383,8 @@ void draw_drag_line( if (card->src_drag && card->snk_drag) { draw_connection( cr, - x1, y1, card->src_drag->port_category == PC_MIX, - x2, y2, card->snk_drag->port_category == PC_MIX, + x1, y1, card->src_drag->port_category, + x2, y2, card->snk_drag->port_category, 0, 0, 0, 2 ); diff --git a/src/window-routing.c b/src/window-routing.c index 45df3fc..fdf5b82 100644 --- a/src/window-routing.c +++ b/src/window-routing.c @@ -30,6 +30,8 @@ static void get_routing_srcs(struct alsa_card *card) { if (strncmp(name, "Mix", 3) == 0) r->port_category = PC_MIX; + else if (strncmp(name, "DSP", 3) == 0) + r->port_category = PC_DSP; else if (strncmp(name, "PCM", 3) == 0) r->port_category = PC_PCM; else @@ -93,6 +95,8 @@ static void get_routing_snks(struct alsa_card *card) { r->elem = elem; if (strncmp(elem->name, "Mixer Input", 11) == 0) { 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) { r->port_category = PC_PCM; } 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) { 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_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", 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", "Mixer\nInputs", 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 ); + 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( - 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( - 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( - 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( - 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( + 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( - routing_grid, card->routing_mixer_in_grid, 1, 0, 1, 1 - ); - 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_grid_set_spacing(routing_grid, 10); GtkWidget *src_label = gtk_label_new("↑\nSources →"); 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↓"); 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) { @@ -759,9 +788,22 @@ static void make_routing_alsa_elem(struct routing_snk *r_snk) { struct alsa_elem *elem = r_snk->elem; 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 - 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]; @@ -840,7 +882,20 @@ static void add_routing_widgets( 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( card, r_src, r_src->name + 4, GTK_ORIENTATION_VERTICAL );