This repository has been archived on 2025-09-15. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
alsa-scarlett-gui/src/alsa.h
Geoffrey D. Bennett c661b4a915 Display input labels across the top of the mixer window
Especially for the 18i20, having labels across the top as well as
along the bottom makes it easier to follow the grid.
2022-03-14 09:24:52 +10:30

212 lines
5.7 KiB
C

// SPDX-FileCopyrightText: 2022 Geoffrey D. Bennett <g@b4.vu>
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include <alsa/asoundlib.h>
#include <gtk/gtk.h>
#include "const.h"
// simulated cards have card->num set to -1
#define SIMULATED_CARD_NUM -1
// forward definitions
struct alsa_elem;
struct alsa_card;
// typedef for callbacks to update widgets when the alsa element
// notifies of a change
typedef void (AlsaElemCallback)(struct alsa_elem *);
// port categories for routing_src and routing_dst entries
// must match the level meter ordering from the driver
enum {
// Hardware inputs/outputs
PC_HW = 0,
// Mixer inputs/outputs
PC_MIX = 1,
// PCM inputs/outputs
PC_PCM = 2,
// number of port categories
PC_COUNT = 3
};
// names for the port categories
extern const char *port_category_names[PC_COUNT];
// is a drag active, and whether dragging from a routing source or a
// routing destination
enum {
DRAG_TYPE_NONE = 0,
DRAG_TYPE_SRC = 1,
DRAG_TYPE_DST = 2,
};
// entry in alsa_card routing_srcs (routing sources) array
// list of enums that are in the Mixer Input X Capture Enum elements
struct routing_src {
// pointer back to the card this entry is associated with
struct alsa_card *card;
// the enum id of the alsa item
int id;
// PC_MIX, PC_PCM, or PC_HW
int port_category;
// 0-based count within port_category
int port_num;
// the alsa item name
char *name;
// the number (or translated letter; A = 1) in the item name
int lr_num;
// on the routing page, the box widget containing the text and the
// "socket" widget for this routing source
GtkWidget *widget;
// the socket widget
GtkWidget *widget2;
};
// entry in alsa_card routing_dsts (routing destinations) array
// for alsa elements that are routing destinations like Analogue
// Output 01 Playback Enum
// port_category is set to PC_MIX, PC_PCM, PC_HW
// port_num is a count (0-based) within that category
struct routing_dst {
// location within the array
int idx;
// pointer back to the element this entry is associated with
struct alsa_elem *elem;
// PC_MIX, PC_PCM, or PC_HW
int port_category;
// 0-based count within port_category
int port_num;
// the mixer label widgets for this destination
GtkWidget *mixer_label_top;
GtkWidget *mixer_label_bottom;
};
// entry in alsa_card elems (ALSA control elements) array
struct alsa_elem {
// pointer back to the card
struct alsa_card *card;
// ALSA element information
int numid;
const char *name;
int type;
int count;
// for the number (or translated letter; A = 1) in the item name
// TODO: move this to struct routing_dst?
int lr_num;
// the primary GTK widget and callback function for this ALSA
// control element
GtkWidget *widget;
AlsaElemCallback *widget_callback;
// text label for volume controls
// handle for routing controls
// second button for dual controls
GtkWidget *widget2;
// for boolean buttons, the two possible texts
// for dual buttons, the four possible texts
const char *bool_text[4];
// for simulated elements, the current state
int writable;
long value;
// for simulated enumerated elements, the items
int item_count;
char **item_names;
};
struct alsa_card {
int num;
char *device;
char *name;
snd_ctl_t *handle;
struct pollfd pfd;
GArray *elems;
struct alsa_elem *sample_capture_elem;
struct alsa_elem *level_meter_elem;
GArray *routing_srcs;
GArray *routing_dsts;
GIOChannel *io_channel;
guint event_source_id;
GtkWidget *window_main;
GtkWidget *window_routing;
GtkWidget *window_mixer;
GtkWidget *window_levels;
GtkWidget *window_startup;
GtkWidget *window_main_contents;
GtkWidget *routing_grid;
GtkWidget *routing_lines;
GtkWidget *routing_hw_in_grid;
GtkWidget *routing_hw_out_grid;
GtkWidget *routing_pcm_in_grid;
GtkWidget *routing_pcm_out_grid;
GtkWidget *routing_mixer_in_grid;
GtkWidget *routing_mixer_out_grid;
GtkWidget *meters[MAX_METERS];
guint meter_gsource_timer;
int has_speaker_switching;
int has_talkback;
int routing_out_count[PC_COUNT];
int routing_in_count[PC_COUNT];
GMenu *routing_src_menu;
GtkWidget *drag_line;
int drag_type;
struct routing_src *src_drag;
struct routing_dst *dst_drag;
double drag_x, drag_y;
};
// global array of cards
extern GArray *alsa_cards;
// utility
void fatal_alsa_error(const char *msg, int err);
// locate elements or get information about them
struct alsa_elem *get_elem_by_name(GArray *elems, char *name);
struct alsa_elem *get_elem_by_prefix(GArray *elems, char *prefix);
int get_max_elem_by_name(GArray *elems, char *prefix, char *needle);
int is_elem_routing_dst(struct alsa_elem *elem);
// alsa snd_ctl_elem_*() functions
int alsa_get_elem_type(struct alsa_elem *elem);
char *alsa_get_elem_name(struct alsa_elem *elem);
long alsa_get_elem_value(struct alsa_elem *elem);
int *alsa_get_elem_int_values(struct alsa_elem *elem);
void alsa_set_elem_value(struct alsa_elem *elem, long value);
int alsa_get_elem_writable(struct alsa_elem *elem);
int alsa_get_elem_count(struct alsa_elem *elem);
int alsa_get_item_count(struct alsa_elem *elem);
char *alsa_get_item_name(struct alsa_elem *elem, int i);
// add to alsa_cards array
struct alsa_card *card_create(int card_num);
// scan/rescan for cards
void alsa_scan_cards(void);
void alsa_inotify_init(void);