aboutsummaryrefslogtreecommitdiff
path: root/gtk
diff options
context:
space:
mode:
Diffstat (limited to 'gtk')
-rw-r--r--gtk/Makefile.am2
-rw-r--r--gtk/configure.ac1
-rw-r--r--gtk/main.c25
-rw-r--r--gtk/toneview.c107
-rw-r--r--gtk/toneview.h14
5 files changed, 147 insertions, 2 deletions
diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index e765244..665f3ca 100644
--- a/gtk/Makefile.am
+++ b/gtk/Makefile.am
@@ -15,6 +15,8 @@ FMDSP_SRC=../fmdsp/fmdsp.c \
../fmdsp/font_fmdsp_small.c
fmplayer_SOURCES=main.c \
+ toneview.c \
+ ../tonedata/tonedata.c \
$(LIBOPNA_SRC) \
$(FMDRIVER_SRC) \
$(FMDSP_SRC)
diff --git a/gtk/configure.ac b/gtk/configure.ac
index bde5f6e..8e13a34 100644
--- a/gtk/configure.ac
+++ b/gtk/configure.ac
@@ -1,5 +1,6 @@
AC_INIT([fmplayer], [0.1.0])
AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects])
+AM_SILENT_RULES([yes])
AC_PROG_CC_C99
dnl AM_PATH_SDL2([2.0.5])
diff --git a/gtk/main.c b/gtk/main.c
index 9e2e989..cd3ddb2 100644
--- a/gtk/main.c
+++ b/gtk/main.c
@@ -5,12 +5,14 @@
#include <stdint.h>
#include <stdbool.h>
#include <cairo.h>
+#include <stdatomic.h>
#include "fmdriver/fmdriver_fmp.h"
#include "fmdriver/ppz8.h"
#include "libopna/opna.h"
#include "libopna/opnatimer.h"
#include "fmdsp/fmdsp.h"
+#include "toneview.h"
#define DATADIR "/.local/share/fmplayer/"
//#define FMDSP_2X
@@ -64,6 +66,10 @@ static void on_menu_quit(GtkMenuItem *menuitem, gpointer ptr) {
quit();
}
+static void on_tone_view(GtkMenuItem *menuitem, gpointer ptr) {
+ show_toneview();
+}
+
static void msgbox_err(const char *msg) {
GtkWidget *d = gtk_message_dialog_new(GTK_WINDOW(g.mainwin), GTK_DIALOG_MODAL,
GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE,
@@ -81,6 +87,13 @@ static int pastream_cb(const void *inptr, void *outptr, unsigned long frames,
int16_t *buf = (int16_t *)outptr;
memset(outptr, 0, sizeof(int16_t)*frames*2);
opna_timer_mix(timer, buf, frames);
+
+ bool xchg = false;
+ if (atomic_compare_exchange_weak_explicit(&toneview_g.flag, &xchg, true,
+ memory_order_acquire, memory_order_relaxed)) {
+ tonedata_from_opna(&toneview_g.tonedata, &g.opna);
+ atomic_store_explicit(&toneview_g.flag, false, memory_order_release);
+ }
return paContinue;
}
@@ -401,6 +414,14 @@ static GtkWidget *create_menubar() {
GtkWidget *quit = gtk_menu_item_new_with_label("Quit");
g_signal_connect(quit, "activate", G_CALLBACK(on_menu_quit), 0);
gtk_menu_shell_append(GTK_MENU_SHELL(menu), quit);
+
+ GtkWidget *window = gtk_menu_item_new_with_label("Window");
+ GtkWidget *filemenu = gtk_menu_new();
+ gtk_menu_item_set_submenu(GTK_MENU_ITEM(window), filemenu);
+ gtk_menu_shell_append(GTK_MENU_SHELL(menubar), window);
+ GtkWidget *toneview = gtk_menu_item_new_with_label("Tone view");
+ g_signal_connect(toneview, "activate", G_CALLBACK(on_tone_view), 0);
+ gtk_menu_shell_append(GTK_MENU_SHELL(filemenu), toneview);
return menubar;
}
@@ -452,7 +473,7 @@ static void mask_update(void) {
static void mask_set(unsigned mask, bool shift) {
if (shift) {
- opna_set_mask(&g.opna, mask);
+ opna_set_mask(&g.opna, ~mask);
} else {
opna_set_mask(&g.opna, opna_get_mask(&g.opna) ^ mask);
}
@@ -470,7 +491,7 @@ static gboolean key_press_cb(GtkWidget *w,
return TRUE;
}
}
- bool shift = e->key.state & GDK_SHIFT_MASK;
+ bool shift = e->key.state & GDK_CONTROL_MASK;
switch (e->key.keyval) {
case GDK_KEY_F6:
if (g.current_uri) {
diff --git a/gtk/toneview.c b/gtk/toneview.c
new file mode 100644
index 0000000..79750fe
--- /dev/null
+++ b/gtk/toneview.c
@@ -0,0 +1,107 @@
+#include <gtk/gtk.h>
+#include "toneview.h"
+#include <stdatomic.h>
+#include <stdbool.h>
+
+struct toneview_g toneview_g;
+
+static struct {
+ GtkWidget *tonewin;
+ GtkWidget *label[6];
+ struct fmplayer_tonedata tonedata;
+ struct fmplayer_tonedata tonedata_n;
+ char strbuf[FMPLAYER_TONEDATA_STR_SIZE];
+ enum fmplayer_tonedata_format format;
+ bool normalize;
+ GtkClipboard *clipboard;
+} g;
+
+static void on_destroy(GtkWidget *w, gpointer ptr) {
+ (void)w;
+ (void)ptr;
+ g.tonewin = 0;
+}
+
+gboolean tick_cb(GtkWidget *widget, GdkFrameClock *clock, gpointer ptr) {
+ (void)widget;
+ (void)clock;
+ (void)ptr;
+ bool xchg = false;
+ if (atomic_compare_exchange_weak_explicit(&toneview_g.flag, &xchg, true,
+ memory_order_acquire, memory_order_relaxed)) {
+ g.tonedata = toneview_g.tonedata;
+ atomic_store_explicit(&toneview_g.flag, false, memory_order_release);
+ }
+ g.tonedata_n = g.tonedata;
+ for (int c = 0; c < 6; c++) {
+ if (g.normalize) {
+ tonedata_ch_normalize_tl(&g.tonedata_n.ch[c]);
+ }
+ tonedata_ch_string(g.format, g.strbuf, &g.tonedata_n.ch[c], 0);
+ gtk_label_set_text(GTK_LABEL(g.label[c]), g.strbuf);
+ }
+ return G_SOURCE_CONTINUE;
+}
+
+static void on_format_changed(GtkComboBox *widget, gpointer ptr) {
+ (void)ptr;
+ g.format = gtk_combo_box_get_active(widget);
+}
+
+static void on_normalize_toggled(GtkToggleButton *widget, gpointer ptr) {
+ (void)ptr;
+ g.normalize = gtk_toggle_button_get_active(widget);
+}
+
+static void on_copy_clicked(GtkButton *button, gpointer ptr) {
+ (void)button;
+ int c = (intptr_t)ptr;
+ if (!g.clipboard) {
+ GdkDisplay *disp = gdk_display_get_default();
+ if (disp) {
+ g.clipboard = gtk_clipboard_get_default(disp);
+ }
+ }
+ if (g.clipboard) {
+ tonedata_ch_string(g.format, g.strbuf, &g.tonedata_n.ch[c], 0);
+ gtk_clipboard_set_text(g.clipboard, g.strbuf, -1);
+ }
+}
+
+void show_toneview(void) {
+ if (!g.tonewin) {
+ g.tonewin = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_title(GTK_WINDOW(g.tonewin), "FM Tone Viewer");
+ g_signal_connect(g.tonewin, "destroy", G_CALLBACK(on_destroy), 0);
+ GtkWidget *box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
+ gtk_container_add(GTK_CONTAINER(g.tonewin), box);
+ GtkWidget *ctrlbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
+ gtk_container_add(GTK_CONTAINER(box), ctrlbox);
+ GtkWidget *format = gtk_combo_box_text_new();
+ gtk_box_pack_start(GTK_BOX(ctrlbox), format, FALSE, TRUE, 0);
+ gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(format), "PMD");
+ gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(format), "FMP");
+ gtk_combo_box_set_active(GTK_COMBO_BOX(format), g.format);
+ g_signal_connect(format, "changed", G_CALLBACK(on_format_changed), 0);
+ GtkWidget *normalizecheck = gtk_check_button_new_with_label("Normalize");
+ gtk_box_pack_start(GTK_BOX(ctrlbox), normalizecheck, FALSE, TRUE, 0);
+ g_signal_connect(normalizecheck, "toggled", G_CALLBACK(on_normalize_toggled), 0);
+ for (int c = 0; c < 6; c++) {
+ GtkWidget *cbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
+ gtk_box_pack_start(GTK_BOX(box), cbox, TRUE, TRUE, 0);
+ GtkWidget *tonetext = gtk_label_new(0);
+ PangoAttrList *pattrl = pango_attr_list_new();
+ PangoAttribute *pattr = pango_attr_family_new("monospace");
+ pango_attr_list_insert(pattrl, pattr);
+ gtk_label_set_attributes(GTK_LABEL(tonetext), pattrl);
+ pango_attr_list_unref(pattrl);
+ gtk_box_pack_start(GTK_BOX(cbox), tonetext, TRUE, TRUE, 0);
+ GtkWidget *copybutton = gtk_button_new_with_label("Copy");
+ g_signal_connect(copybutton, "clicked", G_CALLBACK(on_copy_clicked), (gpointer)((intptr_t)c));
+ gtk_box_pack_start(GTK_BOX(cbox), copybutton, FALSE, TRUE, 0);
+ g.label[c] = tonetext;
+ }
+ gtk_widget_add_tick_callback(g.tonewin, tick_cb, 0, 0);
+ gtk_widget_show_all(g.tonewin);
+ }
+}
diff --git a/gtk/toneview.h b/gtk/toneview.h
new file mode 100644
index 0000000..51c1769
--- /dev/null
+++ b/gtk/toneview.h
@@ -0,0 +1,14 @@
+#ifndef MYON_FMPLAYER_GTK_TONEVIEW_H_INCLUDED
+#define MYON_FMPLAYER_GTK_TONEVIEW_H_INCLUDED
+
+#include "tonedata/tonedata.h"
+#include <stdatomic.h>
+
+extern struct toneview_g {
+ struct fmplayer_tonedata tonedata;
+ atomic_bool flag;
+} toneview_g;
+
+void show_toneview();
+
+#endif // MYON_FMPLAYER_GTK_TONEVIEW_H_INCLUDED