diff options
| author | Takamichi Horikawa <takamichiho@gmail.com> | 2017-03-27 23:32:18 +0900 | 
|---|---|---|
| committer | Takamichi Horikawa <takamichiho@gmail.com> | 2017-03-27 23:32:18 +0900 | 
| commit | 0073f2b8befc6163f2970cb7a01e75fffc95994e (patch) | |
| tree | aab8d559720269e65b5ad05c07d98a865ff14e57 /gtk | |
| parent | e2ee18347d45e4620a8279afb8b0bc4a809441ef (diff) | |
refactor common file loading functions
Diffstat (limited to 'gtk')
| -rw-r--r-- | gtk/Makefile.am | 3 | ||||
| -rw-r--r-- | gtk/main.c | 285 | 
2 files changed, 42 insertions, 246 deletions
| diff --git a/gtk/Makefile.am b/gtk/Makefile.am index 970bf73..174f5e9 100644 --- a/gtk/Makefile.am +++ b/gtk/Makefile.am @@ -18,7 +18,10 @@ FMDSP_SRC=../fmdsp/fmdsp.c \  fmplayer_SOURCES=main.c \                   toneview.c \ +                 oscilloview.c \                   ../tonedata/tonedata.c \ +                 ../common/fmplayer_file.c \ +                 ../common/fmplayer_file_gio.c \                   $(LIBOPNA_SRC) \                   $(FMDRIVER_SRC) \                   $(FMDSP_SRC) @@ -7,6 +7,7 @@  #include <cairo.h>  #include <stdatomic.h> +#include "common/fmplayer_file.h"  #include "fmdriver/fmdriver_fmp.h"  #include "fmdriver/fmdriver_pmd.h"  #include "fmdriver/ppz8.h" @@ -14,6 +15,8 @@  #include "libopna/opnatimer.h"  #include "fmdsp/fmdsp.h"  #include "toneview.h" +#include "oscillo/oscillo.h" +#include "oscilloview.h"  #define DATADIR "/.local/share/fmplayer/"  //#define FMDSP_2X @@ -24,11 +27,6 @@ enum {    AUDIOBUFLEN = 0,  }; -union drivers { -  struct driver_pmd pmd; -  struct driver_fmp fmp; -}; -  static struct {    GtkWidget *mainwin;    bool pa_initialized; @@ -42,15 +40,15 @@ static struct {    char drum_rom[OPNA_ROM_SIZE];    bool drum_rom_loaded;    char adpcm_ram[OPNA_ADPCM_RAM_SIZE]; -  union drivers *driver; +  struct fmplayer_file *fmfile;    void *data; -  void *ppzbuf;    uint8_t vram[PC98_W*PC98_H];    struct fmdsp_font font98;    uint8_t font98data[FONT_ROM_FILESIZE];    void *vram32;    int vram32_stride;    const char *current_uri; +  struct oscillodata oscillodata_audiothread[LIBOPNA_OSCILLO_TRACK_COUNT];  } g;  static void quit(void) { @@ -58,9 +56,7 @@ static void quit(void) {      Pa_CloseStream(g.pastream);    }    if (g.pa_initialized) Pa_Terminate(); -  free(g.driver); -  free(g.data); -  free(g.ppzbuf); +  fmplayer_file_free(g.fmfile);    gtk_main_quit();  } @@ -76,6 +72,10 @@ static void on_tone_view(GtkMenuItem *menuitem, gpointer ptr) {    show_toneview();  } +static void on_oscillo_view(GtkMenuItem *menuitem, gpointer ptr) { +  show_oscilloview(); +} +  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, @@ -92,13 +92,18 @@ static int pastream_cb(const void *inptr, void *outptr, unsigned long frames,    struct opna_timer *timer = (struct opna_timer *)userdata;    int16_t *buf = (int16_t *)outptr;    memset(outptr, 0, sizeof(int16_t)*frames*2); -  opna_timer_mix(timer, buf, frames); +  opna_timer_mix_oscillo(timer, buf, frames, g.oscillodata_audiothread);    if (!atomic_flag_test_and_set_explicit(        &toneview_g.flag, memory_order_acquire)) {      tonedata_from_opna(&toneview_g.tonedata, &g.opna);      atomic_flag_clear_explicit(&toneview_g.flag, memory_order_release); -  }   +  } +  if (!atomic_flag_test_and_set_explicit( +    &oscilloview_g.flag, memory_order_acquire)) { +    memcpy(oscilloview_g.oscillodata, g.oscillodata_audiothread, sizeof(oscilloview_g.oscillodata)); +    atomic_flag_clear_explicit(&oscilloview_g.flag, memory_order_release); +  }    return paContinue;  } @@ -131,153 +136,6 @@ static uint8_t opna_status_libopna(struct fmdriver_work *work, bool a1) {    return status;  } -static GFileInputStream *pcmfilesearch(GFile *dir, const char *name) { -  char *name_l = malloc(strlen(name)); -  if (name_l) { -    strcpy(name_l, name); -    // TODO: not SJIS aware -    for (char *c = name_l; *c; c++) { -      if (('A' <= *c) && (*c <= 'Z')) { -        *c += ('a' - 'A'); -      } -    } -  } -  GFile *file = g_file_get_child(dir, name); -  GFileInputStream *stream = g_file_read(file, 0, 0); -  g_object_unref(G_OBJECT(file)); -  if (stream) { -    free(name_l); -    return stream; -  } -  if (name_l) { -    file = g_file_get_child(dir, name_l); -    free(name_l); -    stream = g_file_read(file, 0, 0); -    g_object_unref(G_OBJECT(file)); -    if (stream) return stream; -  } -  return 0; -} - -static GFileInputStream *extsearch(GFile *dir, const char *base, const char *ext) { -  char *name = malloc(strlen(base) + strlen(ext) + 1); -  if (!name) return 0; -  strcpy(name, base); -  strcat(name, ext); -  GFileInputStream *ret = pcmfilesearch(dir, name); -  free(name); -  return ret; -} - -static bool loadpvi(struct fmdriver_work *work, -                    struct driver_fmp *fmp, -                    GFile *dir) { -  // no need to load, always success -  if(strlen(fmp->pvi_name) == 0) return true; -  GFileInputStream *pvistream = extsearch(dir, fmp->pvi_name, ".PVI"); -  if (!pvistream) goto err; -  void *data = malloc(OPNA_ADPCM_RAM_SIZE); -  if (!data) goto err_stream; -  gsize read; -  if (!g_input_stream_read_all( -    G_INPUT_STREAM(pvistream), data, OPNA_ADPCM_RAM_SIZE, &read, 0, 0 -  )) goto err_data; -  if (!fmp_adpcm_load(work, data, OPNA_ADPCM_RAM_SIZE)) goto err_data; -  free(data); -  g_object_unref(pvistream); -  return true; -err_data: -  free(data); -err_stream: -  g_object_unref(G_OBJECT(pvistream)); -err: -  return false; -} - -static bool loadppzpvi(struct fmdriver_work *work, -                    struct driver_fmp *fmp, -                    GFile *dir) { -  // no need to load, always success -  if(strlen(fmp->ppz_name) == 0) return true; -  GFileInputStream *pvistream = extsearch(dir, fmp->ppz_name, ".PVI"); -  if (!pvistream) goto err; -  GFileInfo *pviinfo = g_file_input_stream_query_info( -    pvistream, G_FILE_ATTRIBUTE_STANDARD_SIZE, -    0, 0); -  if (!pviinfo) goto err_stream; -  gsize fsize; -  { -    goffset sfsize = g_file_info_get_size(pviinfo); -    if (sfsize < 0) goto err_info; -    fsize = sfsize; -  } -  void *data = malloc(fsize); -  if (!data) goto err_info; -  gsize readsize; -  g_input_stream_read_all(G_INPUT_STREAM(pvistream), -                          data, fsize, &readsize, 0, 0); -  if (readsize != fsize) goto err_memory; -  int16_t *decbuf = calloc(ppz8_pvi_decodebuf_samples(fsize), sizeof(int16_t)); -  if (!decbuf) goto err_memory; -  if (!ppz8_pvi_load(work->ppz8, 0, data, fsize, decbuf)) goto err_decbuf; -  free(g.ppzbuf); -  g.ppzbuf = decbuf; -  free(data); -  g_object_unref(G_OBJECT(pviinfo)); -  g_object_unref(G_OBJECT(pvistream)); -  return true; -err_decbuf: -  free(decbuf); -err_memory: -  free(data); -err_info: -  g_object_unref(pviinfo); -err_stream: -  g_object_unref(pvistream); -err: -  return false; -} - -static bool loadppc(struct fmdriver_work *work, -                    struct driver_pmd *pmd, -                    GFile *dir) { -  // no need to load, always success -  if(strlen(pmd->ppcfile) == 0) return true; -  fprintf(stderr, "PPC: %s\n", pmd->ppcfile); -  GFileInputStream *stream = extsearch(dir, pmd->ppcfile,  ".PPC"); -  if (!stream) goto err; -  GFileInfo *info = g_file_input_stream_query_info( -    stream, G_FILE_ATTRIBUTE_STANDARD_SIZE, -    0, 0); -  if (!info) goto err_stream; -  gsize fsize; -  { -    goffset sfsize = g_file_info_get_size(info); -    if (sfsize < 0) goto err_info; -    fsize = sfsize; -  } -  void *data = malloc(fsize); -  if (!data) goto err_info; -  gsize read; -  if (!g_input_stream_read_all( -    G_INPUT_STREAM(stream), data, fsize, &read, 0, 0 -  )) goto err_data; -  if (read != fsize) goto err_data; -  if (!pmd_ppc_load(work, data, fsize)) goto err_data; -  free(data); -  g_object_unref(G_OBJECT(info)); -  g_object_unref(G_OBJECT(stream)); -  return true; -err_data: -  free(data); -err_info: -  g_object_unref(G_OBJECT(info)); -err_stream: -  g_object_unref(G_OBJECT(stream)); -err: -  return false; -} -  static void load_drumrom(void) {    const char *path = "ym2608_adpcm_rom.bin";    const char *home = getenv("HOME"); @@ -343,82 +201,41 @@ err:  }  static bool openfile(const char *uri) { -  enum { -    DRIVER_PMD, -    DRIVER_FMP -  } driver_type; +  struct fmplayer_file *fmfile = 0;    if (!g.pa_initialized) {      msgbox_err("Could not initialize Portaudio");      goto err;    } -  GFile *fmfile = g_file_new_for_uri(uri); -  GFileInfo *fminfo = g_file_query_info( -    fmfile, G_FILE_ATTRIBUTE_STANDARD_SIZE, -    0, 0, 0 -  ); -  if (!fminfo) { -    msgbox_err("Cannot get size information for file"); -    goto err_file; -  } -  gsize filelen; -  { -    goffset sfilelen = g_file_info_get_size(fminfo); -    if (sfilelen < 0) { -      goto err_info; -    } -    filelen = sfilelen; -  } -  GFileInputStream *fmstream = g_file_read(fmfile, 0, 0); -  if (!fmstream) { -    msgbox_err("cannot open file for read"); -    goto err_info; -  } -  void *fmbuf = malloc(filelen); -  if (!fmbuf) { -    msgbox_err("cannot allocate memory for file"); -    goto err_stream; -  } -  gsize fileread; -  g_input_stream_read_all( -    G_INPUT_STREAM(fmstream), fmbuf, filelen, &fileread, 0, 0); -  if (fileread != filelen) { -    msgbox_err("cannot read file"); -    goto err_buf; -  } -  union drivers *driver = calloc(1, sizeof(*driver)); -  if (!driver) { -    msgbox_err("cannot allocate memory for fmp"); -    goto err_buf; -  } -  if (fmp_load(&driver->fmp, fmbuf, filelen)) { -    driver_type = DRIVER_FMP; -  } else { -    memset(driver, 0, sizeof(*driver)); -    if (pmd_load(&driver->pmd, fmbuf, filelen)) { -      driver_type = DRIVER_PMD; -    } else { -      msgbox_err("invalid file"); -      goto err_driver; +  enum fmplayer_file_error error; +  fmfile = fmplayer_file_alloc(uri, &error); +  if (!fmfile) { +    const char *errstr = fmplayer_file_strerror(error); +    const char *errmain = "cannot load file: "; +    char *errbuf = malloc(strlen(errstr) + strlen(errmain) + 1); +    if (errbuf) { +      strcpy(errbuf, errmain); +      strcat(errbuf, errstr);      } +    msgbox_err(errbuf ? errbuf : "cannot load file"); +    free(errbuf); +    goto err;    }    if (!g.pastream) {      PaError pe = Pa_OpenDefaultStream(&g.pastream, 0, 2, paInt16, SRATE, AUDIOBUFLEN,                                        pastream_cb, &g.opna_timer);      if (pe != paNoError) {        msgbox_err("cannot open portaudio stream"); -      goto err_driver; +      goto err;      }    } else if (!g.pa_paused) {      PaError pe = Pa_StopStream(g.pastream);      if (pe != paNoError) {        msgbox_err("Portaudio Error"); -      goto err_driver; +      goto err;      }    } -  free(g.driver); -  g.driver = driver; -  free(g.data); -  g.data = fmbuf; +  fmplayer_file_free(g.fmfile); +  g.fmfile = fmfile;    unsigned mask = opna_get_mask(&g.opna);    opna_reset(&g.opna);    opna_set_mask(&g.opna, mask); @@ -447,26 +264,8 @@ static bool openfile(const char *uri) {    }    opna_timer_set_int_callback(&g.opna_timer, opna_int_cb, &g.work);    opna_timer_set_mix_callback(&g.opna_timer, opna_mix_cb, &g.ppz8); -  if (driver_type == DRIVER_FMP) { -    fmp_init(&g.work, &g.driver->fmp); -    GFile *dir = g_file_get_parent(fmfile); -    if (dir) { -      loadpvi(&g.work, &g.driver->fmp, dir); -      loadppzpvi(&g.work, &g.driver->fmp, dir); -      g_object_unref(G_OBJECT(dir)); -    } -  } else { -    pmd_init(&g.work, &g.driver->pmd); -    GFile *dir = g_file_get_parent(fmfile); -    if (dir) { -      loadppc(&g.work, &g.driver->pmd, dir); -      g_object_unref(G_OBJECT(dir)); -    } -  } +  fmplayer_file_load(&g.work, g.fmfile);    fmdsp_vram_init(&g.fmdsp, &g.work, g.vram); -  g_object_unref(G_OBJECT(fmstream)); -  g_object_unref(G_OBJECT(fminfo)); -  g_object_unref(G_OBJECT(fmfile));    Pa_StartStream(g.pastream);    g.pa_paused = false;    { @@ -475,17 +274,8 @@ static bool openfile(const char *uri) {      g.current_uri = turi;    }    return true; -err_driver: -  free(driver); -err_buf: -  free(fmbuf); -err_stream: -  g_object_unref(G_OBJECT(fmstream)); -err_info: -  g_object_unref(G_OBJECT(fminfo)); -err_file: -  g_object_unref(G_OBJECT(fmfile));  err: +  fmplayer_file_free(fmfile);    return false;  } @@ -517,6 +307,9 @@ static GtkWidget *create_menubar() {    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); +  GtkWidget *oscilloview = gtk_menu_item_new_with_label("Oscillo view"); +  g_signal_connect(oscilloview, "activate", G_CALLBACK(on_oscillo_view), 0); +  gtk_menu_shell_append(GTK_MENU_SHELL(filemenu), oscilloview);    return menubar;  } | 
