diff options
| author | Takamichi Horikawa <takamichiho@gmail.com> | 2017-03-27 23:33:40 +0900 | 
|---|---|---|
| committer | Takamichi Horikawa <takamichiho@gmail.com> | 2017-03-27 23:33:40 +0900 | 
| commit | 30c59a00956142aafda87c0bdc71c46d1a2218ff (patch) | |
| tree | 0bf1c81767dc8edb86ade2a4e224392e2ac5280b /gtk | |
| parent | 0073f2b8befc6163f2970cb7a01e75fffc95994e (diff) | |
add oscilloscope view
Diffstat (limited to 'gtk')
| -rw-r--r-- | gtk/oscilloview.c | 83 | ||||
| -rw-r--r-- | gtk/oscilloview.h | 17 | 
2 files changed, 100 insertions, 0 deletions
| diff --git a/gtk/oscilloview.c b/gtk/oscilloview.c new file mode 100644 index 0000000..724ada9 --- /dev/null +++ b/gtk/oscilloview.c @@ -0,0 +1,83 @@ +#include <gtk/gtk.h> +#include <cairo.h> +#include "oscilloview.h" +#include <string.h> + +struct oscilloview oscilloview_g = { +  .flag = ATOMIC_FLAG_INIT +}; + +enum { +  VIEW_SAMPLES = 1024, +  VIEW_SKIP = 2, +  WIDTH = 600, +  HEIGHT = 300, +}; + +static struct { +  GtkWidget *win; +  struct oscillodata oscillodata[LIBOPNA_OSCILLO_TRACK_COUNT]; +} g; + +static void on_destroy(GtkWidget *w, gpointer ptr) { +  (void)w; +  (void)ptr; +  g.win = 0; +} + +static void draw_track(cairo_t *cr, +                       double x, double y, double w, double h, +                       const struct oscillodata *data) { +  int start = OSCILLO_SAMPLE_COUNT - VIEW_SAMPLES; +  start -= (data->offset >> OSCILLO_OFFSET_SHIFT); +  if (start < 0) start = 0; +  for (int i = 0; i < (VIEW_SAMPLES / VIEW_SKIP); i++) { +    cairo_line_to(cr, x + ((i)*w)/(VIEW_SAMPLES / VIEW_SKIP), y + h/2.0 - (data[0].buf[start + i*VIEW_SKIP] / 16384.0) * h/2); +  } +  cairo_stroke(cr); +} + +static gboolean draw_cb(GtkWidget *w, +                        cairo_t *cr, +                        gpointer ptr) { +  (void)w; +  (void)ptr; +  cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE); +  if (!atomic_flag_test_and_set_explicit( +    &oscilloview_g.flag, memory_order_acquire)) { +    memcpy(g.oscillodata, +           oscilloview_g.oscillodata, +           sizeof(oscilloview_g.oscillodata)); +    atomic_flag_clear_explicit(&oscilloview_g.flag, memory_order_release); +  } +  cairo_set_source_rgb(cr, 0.0, 0.0, 0.0); +  cairo_paint(cr); +  cairo_set_source_rgb(cr, 1.0, 1.0, 1.0); +  for (int x = 0; x < 3; x++) { +    for (int y = 0; y < 3; y++) { +      draw_track(cr, x*WIDTH, y*HEIGHT, WIDTH, HEIGHT, &g.oscillodata[x*3+y]); +    } +  } +  return FALSE; +} + +static gboolean tick_cb(GtkWidget *w, GdkFrameClock *clock, gpointer ptr) { +  (void)clock; +  (void)ptr; +  gtk_widget_queue_draw(w); +  return G_SOURCE_CONTINUE; +} + +void show_oscilloview(void) { +  if (!g.win) { +    g.win = gtk_window_new(GTK_WINDOW_TOPLEVEL); +    gtk_window_set_title(GTK_WINDOW(g.win), "Oscilloscope view"); +    g_signal_connect(g.win, "destroy", G_CALLBACK(on_destroy), 0); +  } +  GtkWidget *drawarea = gtk_drawing_area_new(); +  gtk_container_add(GTK_CONTAINER(g.win), drawarea); +  gtk_widget_set_size_request(drawarea, WIDTH*3, HEIGHT*3); +  g_signal_connect(drawarea, "draw", G_CALLBACK(draw_cb), 0); +  gtk_widget_add_tick_callback(drawarea, tick_cb, 0, 0); +  gtk_widget_show_all(g.win); +} diff --git a/gtk/oscilloview.h b/gtk/oscilloview.h new file mode 100644 index 0000000..edabcd9 --- /dev/null +++ b/gtk/oscilloview.h @@ -0,0 +1,17 @@ +#ifndef MYON_FMPLAYER_GTK_OSCILLOVIEW_H_INCLUDED +#define MYON_FMPLAYER_GTK_OSCILLOVIEW_H_INCLUDED + +#include "libopna/opna.h" +#include "oscillo/oscillo.h" + +#include <stdatomic.h> + +extern struct oscilloview { +  atomic_flag flag; +  struct oscillodata oscillodata[LIBOPNA_OSCILLO_TRACK_COUNT]; +} oscilloview_g; + +void show_oscilloview(void); + +#endif // MYON_FMPLAYER_GTK_OSCILLOVIEW_H_INCLUDED + | 
