From 23dc19065c182e61bce9c997f31e23b001a85f2c Mon Sep 17 00:00:00 2001 From: Takamichi Horikawa Date: Wed, 1 Mar 2017 00:22:33 +0900 Subject: gtk: add tone viewer --- gtk/Makefile.am | 2 ++ gtk/configure.ac | 1 + gtk/main.c | 25 +++++++++++-- gtk/toneview.c | 107 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ gtk/toneview.h | 14 ++++++++ 5 files changed, 147 insertions(+), 2 deletions(-) create mode 100644 gtk/toneview.c create mode 100644 gtk/toneview.h (limited to 'gtk') 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 #include #include +#include #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 +#include "toneview.h" +#include +#include + +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 + +extern struct toneview_g { + struct fmplayer_tonedata tonedata; + atomic_bool flag; +} toneview_g; + +void show_toneview(); + +#endif // MYON_FMPLAYER_GTK_TONEVIEW_H_INCLUDED -- cgit v1.2.3