Add display of sample rate
This commit is contained in:
@@ -228,6 +228,31 @@ button.toggle {
|
||||
text-shadow: 0 0 5px #00c000, 0 0 15px #00c000;
|
||||
}
|
||||
|
||||
/* Sample Rates */
|
||||
.window-frame button.sample-rate.sample-rate-44100 {
|
||||
text-shadow: 0 0 5px #00c000, 0 0 15px #00c000;
|
||||
}
|
||||
|
||||
.window-frame button.sample-rate.sample-rate-48000 {
|
||||
text-shadow: 0 0 5px #00c000, 0 0 15px #00c000;
|
||||
}
|
||||
|
||||
.window-frame button.sample-rate.sample-rate-88200 {
|
||||
text-shadow: 0 0 5px #ff8000, 0 0 15px #ff8000;
|
||||
}
|
||||
|
||||
.window-frame button.sample-rate.sample-rate-96000 {
|
||||
text-shadow: 0 0 5px #ff8000, 0 0 15px #ff8000;
|
||||
}
|
||||
|
||||
.window-frame button.sample-rate.sample-rate-176400 {
|
||||
text-shadow: 0 0 5px #ff0000, 0 0 15px #c00000;
|
||||
}
|
||||
|
||||
.window-frame button.sample-rate.sample-rate-192000 {
|
||||
text-shadow: 0 0 5px #ff0000, 0 0 15px #c00000;
|
||||
}
|
||||
|
||||
/* Button controls where checked is dimmer */
|
||||
|
||||
/* Mute button */
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "widget-gain.h"
|
||||
#include "widget-input-select.h"
|
||||
#include "widget-label.h"
|
||||
#include "widget-sample-rate.h"
|
||||
#include "window-helper.h"
|
||||
#include "window-levels.h"
|
||||
#include "window-mixer.h"
|
||||
@@ -114,6 +115,30 @@ static void add_power_status_control(
|
||||
gtk_box_append(GTK_BOX(b), w);
|
||||
}
|
||||
|
||||
static void add_sample_rate_control(
|
||||
struct alsa_card *card,
|
||||
GtkWidget *global_controls
|
||||
) {
|
||||
GtkWidget *b = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
|
||||
gtk_widget_set_tooltip_text(
|
||||
b,
|
||||
"The Sample Rate cannot be changed here because it is set by the "
|
||||
"application which is using the interface, usually a sound "
|
||||
"server like PulseAudio, JACK, or PipeWire. If this shows N/A, "
|
||||
"no application is currently using the interface.\n\n"
|
||||
"Note that not all features are available on all interfaces at "
|
||||
"sample rates above 48kHz. Please refer to the user guide for "
|
||||
"your interface for more information."
|
||||
);
|
||||
gtk_box_append(GTK_BOX(global_controls), b);
|
||||
|
||||
GtkWidget *l = gtk_label_new("Sample Rate");
|
||||
gtk_box_append(GTK_BOX(b), l);
|
||||
GtkWidget *w = make_sample_rate_widget(card);
|
||||
gtk_widget_add_css_class(w, "sample-rate");
|
||||
gtk_box_append(GTK_BOX(b), w);
|
||||
}
|
||||
|
||||
static void add_speaker_switching_controls(
|
||||
struct alsa_card *card,
|
||||
GtkWidget *global_controls
|
||||
@@ -690,21 +715,24 @@ static void create_global_controls(
|
||||
? GTK_ORIENTATION_HORIZONTAL
|
||||
: GTK_ORIENTATION_VERTICAL;
|
||||
GtkWidget *global_controls = create_global_box(top, x, orient);
|
||||
GtkWidget *left = global_controls;
|
||||
GtkWidget *right = global_controls;
|
||||
GtkWidget *column[3];
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
column[i] = global_controls;
|
||||
|
||||
if (card->has_speaker_switching) {
|
||||
left = gtk_box_new(GTK_ORIENTATION_VERTICAL, 15);
|
||||
right = gtk_box_new(GTK_ORIENTATION_VERTICAL, 15);
|
||||
gtk_box_append(GTK_BOX(global_controls), left);
|
||||
gtk_box_append(GTK_BOX(global_controls), right);
|
||||
for (int i = 0; i < 3; i++) {
|
||||
column[i] = gtk_box_new(GTK_ORIENTATION_VERTICAL, 15);
|
||||
gtk_box_append(GTK_BOX(global_controls), column[i]);
|
||||
}
|
||||
}
|
||||
|
||||
add_clock_source_control(card, left);
|
||||
add_sync_status_control(card, right);
|
||||
add_power_status_control(card, right);
|
||||
add_speaker_switching_controls(card, left);
|
||||
add_talkback_controls(card, right);
|
||||
add_clock_source_control(card, column[0]);
|
||||
add_sync_status_control(card, column[1]);
|
||||
add_power_status_control(card, column[1]);
|
||||
add_sample_rate_control(card, column[2]);
|
||||
add_speaker_switching_controls(card, column[0]);
|
||||
add_talkback_controls(card, column[1]);
|
||||
}
|
||||
|
||||
static GtkWidget *create_main_window_controls(struct alsa_card *card) {
|
||||
|
||||
123
src/widget-sample-rate.c
Normal file
123
src/widget-sample-rate.c
Normal file
@@ -0,0 +1,123 @@
|
||||
// SPDX-FileCopyrightText: 2024 Geoffrey D. Bennett <g@b4.vu>
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#include "gtkhelper.h"
|
||||
#include "widget-boolean.h"
|
||||
|
||||
struct sample_rate {
|
||||
struct alsa_card *card;
|
||||
GtkWidget *button;
|
||||
guint source;
|
||||
char *path;
|
||||
int sample_rate;
|
||||
};
|
||||
|
||||
static void button_set_text(GtkWidget *button, int value) {
|
||||
gtk_widget_remove_css_classes_by_prefix(button, "sample-rate-");
|
||||
|
||||
if (!value) {
|
||||
gtk_button_set_label(GTK_BUTTON(button), "N/A");
|
||||
return;
|
||||
}
|
||||
|
||||
char *text;
|
||||
if (value % 1000 == 0)
|
||||
text = g_strdup_printf("%dkHz", value / 1000);
|
||||
else
|
||||
text = g_strdup_printf("%.1fkHz", value / 1000.0);
|
||||
gtk_button_set_label(GTK_BUTTON(button), text);
|
||||
g_free(text);
|
||||
|
||||
char *css_class = g_strdup_printf(
|
||||
"sample-rate-%d", value
|
||||
);
|
||||
gtk_widget_add_css_class(button, css_class);
|
||||
g_free(css_class);
|
||||
}
|
||||
|
||||
// Read the sample rate from /proc/asound/cardN/stream0
|
||||
// and return it as an integer
|
||||
//
|
||||
// Looking for a line containing:
|
||||
// Momentary freq = 48000 Hz (0x6.0000)
|
||||
static int get_sample_rate(struct sample_rate *data) {
|
||||
if (!data->path)
|
||||
return 0;
|
||||
|
||||
FILE *file = fopen(data->path, "r");
|
||||
if (!file) {
|
||||
perror("fopen");
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *line = NULL;
|
||||
size_t len = 0;
|
||||
ssize_t read;
|
||||
|
||||
int sample_rate = 0;
|
||||
|
||||
while ((read = getline(&line, &len, file)) != -1) {
|
||||
if (strstr(line, "Momentary freq = ")) {
|
||||
char *start = strstr(line, "Momentary freq = ") + 17;
|
||||
char *end = strstr(start, " Hz");
|
||||
|
||||
if (!start || !end)
|
||||
continue;
|
||||
|
||||
*end = '\0';
|
||||
sample_rate = atoi(start);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
free(line);
|
||||
fclose(file);
|
||||
|
||||
return sample_rate;
|
||||
}
|
||||
|
||||
static gboolean update_sample_rate(struct sample_rate *data) {
|
||||
int sample_rate = get_sample_rate(data);
|
||||
|
||||
if (sample_rate != data->sample_rate) {
|
||||
data->sample_rate = sample_rate;
|
||||
button_set_text(data->button, sample_rate);
|
||||
}
|
||||
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
static void on_destroy(struct sample_rate *data, GObject *widget) {
|
||||
if (data->source)
|
||||
g_source_remove(data->source);
|
||||
g_free(data->path);
|
||||
g_free(data);
|
||||
}
|
||||
|
||||
GtkWidget *make_sample_rate_widget(
|
||||
struct alsa_card *card
|
||||
) {
|
||||
struct sample_rate *data = g_malloc0(sizeof(struct sample_rate));
|
||||
data->card = card;
|
||||
data->button = gtk_toggle_button_new();
|
||||
data->sample_rate = -1;
|
||||
|
||||
gtk_widget_add_css_class(data->button, "fixed");
|
||||
gtk_widget_add_css_class(data->button, "sample-rate");
|
||||
|
||||
// can only update if it's a real card
|
||||
if (card->num != SIMULATED_CARD_NUM) {
|
||||
data->path = g_strdup_printf("/proc/asound/card%d/stream0", card->num);
|
||||
data->source =
|
||||
g_timeout_add_seconds(1, (GSourceFunc)update_sample_rate, data);
|
||||
}
|
||||
|
||||
// initial update (will show "N/A" for simulated card)
|
||||
update_sample_rate(data);
|
||||
|
||||
// cleanup when the button is destroyed
|
||||
g_object_weak_ref(G_OBJECT(data->button), (GWeakNotify)on_destroy, data);
|
||||
|
||||
return data->button;
|
||||
}
|
||||
12
src/widget-sample-rate.h
Normal file
12
src/widget-sample-rate.h
Normal file
@@ -0,0 +1,12 @@
|
||||
// SPDX-FileCopyrightText: 2024 Geoffrey D. Bennett <g@b4.vu>
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "alsa.h"
|
||||
|
||||
GtkWidget *make_sample_rate_widget(
|
||||
struct alsa_card *alsa_card
|
||||
);
|
||||
Reference in New Issue
Block a user