📄 absubs.c
字号:
#include <sys/param.h>#include <xview/xview.h>#include <xview/panel.h>#include <xview/svrimage.h>#include <xview/icon.h>#include <gfm.h>#include "abtool_ui.h"#include "abplay.h"extern abtool_win_objects *Abtool_win;extern abtool_pwin_objects *Abtool_pwin;void files_play_notify();void files_close_notify();void files_graph_notify();void files_seg_notify();void file_loadspd_notify();void file_loadseg_notify();void file_storeseg_notify();Panel_setting align_notify();double get_value_double();double set_panel_dbl();void set_label_char(Xv_opaque, char);Notify_value audio_notify();Notify_value destroy_func();Notify_value open_cmd_files();#define ABLEN 10#define NAMELEN 64struct { int segnum; /* Current segment */ int seginc; /* Increment segments if non-zero */ int nsegs; /* Number of defined segments */ int abnum; /* Current position in ablist (-1 = ignore ablist) */ char ablist[ABLEN]; /* List of files to play in order (ABC etc) */} playlist;gfm_popup_objects *Gfm;static Xv_opaque Flist;static char idchar[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";static char filename[MAXFILES][NAMELEN];static int align_id = -1;static char *play_label[] = {"Play A/B", "Stop"};static int s_argc;static char **s_argv;static char version[] = {#include "version.h"};static unsigned short icon_bits[] = {#include "abtool.icon"};static unsigned short mask_bits[] = {#include "abtool_mask.icon"};/* * Application-specific initialization */voidabtool_initialize(int argc, char **argv){ int i; char pathname[MAXPATHLEN]; Menu menu; Menu_item item; struct segparms parm; Server_image icon_image, mask_image; Icon icon;/* Save filenames from command line to open from event loop */ s_argc = argc; s_argv = argv; playlist.nsegs = 0;/* Create icon */ icon_image = (Server_image)xv_create(NULL, SERVER_IMAGE, SERVER_IMAGE_BITS, icon_bits, XV_WIDTH, 64, XV_HEIGHT, 64, NULL); mask_image = (Server_image)xv_create(NULL, SERVER_IMAGE, SERVER_IMAGE_BITS, mask_bits, XV_WIDTH, 64, XV_HEIGHT, 64, NULL); icon = (Icon)xv_create(Abtool_win->win, ICON, XV_LABEL, "A/B Tool", ICON_IMAGE, icon_image, ICON_MASK_IMAGE, mask_image, NULL);/* Misc window initialization */ Flist = Abtool_win->list1; window_fit(Abtool_win->controls1); window_fit(Abtool_win->win); getcwd(pathname, MAXPATHLEN); xv_set(Abtool_win->win, XV_LABEL, version, FRAME_ICON, icon, FRAME_LEFT_FOOTER, pathname, NULL); xv_set(Abtool_win->controls1, WIN_NOTIFY_EVENT_PROC, open_cmd_files, NULL); xv_set(Abtool_win->canvas1, CANVAS_AUTO_CLEAR, TRUE, CANVAS_FIXED_IMAGE, FALSE, NULL);/* Register audio status notification callback */ notify_set_event_func(SIGPOLL, audio_notify, NOTIFY_SAFE); notify_interpose_destroy_func(Abtool_win->win, destroy_func);/* Set up file chooser */ xv_set(Abtool_pwin->thresh, PANEL_VALUE, 50, 0); xv_set(Abtool_pwin->gap, PANEL_VALUE, 200, 0); xv_set(Abtool_pwin->pad, PANEL_VALUE, 200, 0); xv_set(Abtool_pwin->maxdelay, PANEL_VALUE, "1000", 0); Gfm = gfm_initialize(NULL, Abtool_win->win, "A/B Tool: Load"); xv_set(Abtool_win->play_button, PANEL_LABEL_STRING, play_label[0], 0);/* Attach menu item notify functions, since devguide won't do it. */ menu = (Menu)xv_get(Abtool_win->list1, PANEL_ITEM_MENU); item = (Menu_item)xv_get(menu, MENU_NTH_ITEM, 1); xv_set(item, MENU_NOTIFY_PROC, files_play_notify, NULL); item = (Menu_item)xv_get(menu, MENU_NTH_ITEM, 2); xv_set(item, MENU_NOTIFY_PROC, files_close_notify, NULL); item = (Menu_item)xv_get(menu, MENU_NTH_ITEM, 3); xv_set(item, MENU_NOTIFY_PROC, files_graph_notify, NULL); item = (Menu_item)xv_get(menu, MENU_NTH_ITEM, 4); xv_set(item, MENU_NOTIFY_PROC, files_seg_notify, NULL); menu = (Menu)xv_get(Abtool_win->file_button, PANEL_ITEM_MENU); item = (Menu_item)xv_get(menu, MENU_NTH_ITEM, 2); xv_set(item, MENU_NOTIFY_PROC, file_loadspd_notify, NULL); item = (Menu_item)xv_get(menu, MENU_NTH_ITEM, 3); xv_set(item, MENU_NOTIFY_PROC, file_loadseg_notify, NULL); item = (Menu_item)xv_get(menu, MENU_NTH_ITEM, 4); xv_set(item, MENU_NOTIFY_PROC, file_storeseg_notify, NULL); xv_set(Abtool_pwin->gain, PANEL_NOTIFY_PROC, align_notify, 0); xv_set(Abtool_pwin->delay, PANEL_NOTIFY_PROC, align_notify, 0);}Notify_valueopen_cmd_files(Xv_Window win, Event *event, Notify_arg arg, Notify_event_type type ){ int i; Notify_value value; value = notify_next_event_func(win, event, arg, type); if (event_id(event) == WIN_REPAINT) { for (i=1; i<s_argc; i++) abtool_file_load("", s_argv[i]); s_argc = 0; files_seg_notify(0, 0); show_align(0); } return value;}Notify_valuedestroy_func(Notify_client client, Destroy_status status){ if (status == DESTROY_CLEANUP || status == DESTROY_PROCESS_DEATH) { kill(0, SIGTERM); } return NOTIFY_OK;}/* * Callback for file chooser */gfm_proc(gfm_popup_objects *ip, char *dir, char *file){ return abtool_file_load(dir, file);}voidfile_loadspd_notify(Menu menu, Menu_item menu_item){ gfm_activate(Gfm, NULL, NULL, NULL, gfm_proc, NULL, GFM_LOAD);}voidfile_loadseg_notify(Menu menu, Menu_item menu_item){ printf("load segments not implemented\n");}voidfile_storeseg_notify(Menu menu, Menu_item menu_item){ printf("store segments not implemented\n");}abtool_file_load(char *dir, char *file){ int i, n; if (strlen(dir) > (size_t)0) { if (chdir(dir) < 0) return GFM_ERROR; xv_set(Abtool_win->win, FRAME_LEFT_FOOTER, dir, NULL); } xv_set(Abtool_win->win, FRAME_BUSY, TRUE, NULL); xv_set(Abtool_pwin->pwin, FRAME_BUSY, TRUE, NULL); n = abp_open_file(file); xv_set(Abtool_win->win, FRAME_BUSY, FALSE, NULL); xv_set(Abtool_pwin->pwin, FRAME_BUSY, FALSE, NULL); if (n < 0) return GFM_ERROR; strncpy(filename[n], file, NAMELEN); i = (int)xv_get(Flist, PANEL_LIST_NROWS); if (i <= n) xv_set(Flist, PANEL_LIST_INSERT, n, NULL); show_align(n); show_file(n); return GFM_OK;}show_file(int n){ int n1, n2, show; char str[NAMELEN+10]; n1 = n2 = n; if (n < 0) { n1 = 0; n2 = xv_get(Flist, PANEL_LIST_NROWS) - 1; } show = xv_get(Abtool_pwin->fname, PANEL_VALUE); for (n = n1; n <= n2; n++) { str[0] = 0; if (strlen(filename[n]) > (size_t)0) { sprintf(str, " 0: "); str[2] = idchar[n]; if (show == 0) strncpy(&str[5], filename[n], NAMELEN); } xv_set(Flist, PANEL_LIST_STRING, n, str, NULL); }}list_seln(){ int i, n; for (i=0, n=-1; i<xv_get(Flist, PANEL_LIST_NROWS); i++) if (xv_get(Flist, PANEL_LIST_SELECTED, i)) if (strlen((char *)xv_get(Flist, PANEL_LIST_STRING, i)) > (size_t)0) { n = i; break; } return n;}voidfiles_play_notify(Menu menu, Menu_item menu_item){ playlist.abnum = -1; abp_start_play(list_seln(), 0);}voidfiles_close_notify(Menu menu, Menu_item menu_item){ int i, n, nrows, last; n = list_seln(); if (n < 0) { fprintf(stderr,"Fatal: no list selection"); exit(-1); } abp_close_file(n); filename[n][0] = 0; show_file(n); nrows = (int)xv_get(Flist, PANEL_LIST_NROWS); for (i=0, last=-1; i<nrows; i++) if (strlen(filename[i]) > (size_t)0) last = i; for (i=nrows-1; i>last; i--) xv_set(Flist, PANEL_LIST_DELETE, i, NULL);}voidfiles_graph_notify(Menu menu, Menu_item menu_item){ printf("graph not implemented (%d)\n", list_seln());}voidfiles_seg_notify(Menu menu, Menu_item menu_item){ int id; struct segparms parm; id = MAX(0, list_seln()); parm.thresh = (int)xv_get(Abtool_pwin->thresh, PANEL_VALUE); parm.gap = (int)xv_get(Abtool_pwin->gap, PANEL_VALUE); parm.pad = (int)xv_get(Abtool_pwin->pad, PANEL_VALUE); parm.taumax = .001 * get_value_int(Abtool_pwin->maxdelay); set_panel_int(Abtool_pwin->maxdelay, PANEL_VALUE, nint(1000.*parm.taumax)); playlist.nsegs = abp_segment(id, parm); set_label_char(Abtool_pwin->ref, idchar[id]); set_panel_int(Abtool_win->nsegs_text, PANEL_LABEL_STRING, playlist.nsegs); show_align(id);}Notify_valueaudio_notify(Notify_client client, Notify_event event, Notify_arg arg, Notify_event_type when){ int n, id; struct audio_status status;/* Update selection to indicate which file is playing */ abp_get_audio_status(&status); if (status.state == IDLE) { for (n=0; n<(int)xv_get(Flist, PANEL_LIST_NROWS); n++) xv_set(Flist, PANEL_LIST_SELECT, n, FALSE, NULL); start_play(0); /* Start playing next file/segment */ n = 0; /* Play button = "Play" */ if (playlist.abnum >= 0) n = -1; /* Don't flicker if queued */ } else { xv_set(Flist, PANEL_LIST_SELECT, status.id, TRUE, NULL); n = 1; /* Play button = "Stop" */ } if (n >= 0) { xv_set(Abtool_win->play_button, PANEL_LABEL_STRING, play_label[n], NULL); if (n == 0) if (xv_get(Abtool_pwin->audio_hold, PANEL_VALUE)) abp_close_device(); } return NOTIFY_DONE;}/* * Play: id > 0 - play a single segment from the file "id" (a,b,etc) * = 0 - continue play with the next element in list * < 0 - initialize A/B list, start play with first element */start_play(int id){ int n; char *cp;/* Play A/B button: Initialize A/B list, play first element */ playlist.segnum = get_segnum(); if (id < 0) { strncpy(playlist.ablist, (char *)xv_get(Abtool_win->ab_text, PANEL_VALUE), ABLEN-1); if (strlen(playlist.ablist) == (size_t)0) { n = xv_get(Flist, PANEL_LIST_NROWS); strncpy(playlist.ablist, idchar, n); xv_set(Abtool_win->ab_text, PANEL_VALUE, playlist.ablist, 0); } playlist.abnum = 0; playlist.seginc = 1; if (playlist.segnum > 0 && playlist.segnum <= playlist.nsegs) { playlist.seginc = 0; } else { playlist.segnum = 1; } id = (int)playlist.ablist[playlist.abnum]; }/* Idle notify: Play next element from list, if any */ else if (id == 0) { if (playlist.abnum >= 0) { playlist.abnum += 1; if ((size_t)playlist.abnum >= strlen(playlist.ablist)) { playlist.abnum = 0; if (playlist.seginc == 0) playlist.abnum = -1; else { playlist.segnum += 1; if (playlist.segnum > playlist.nsegs) { playlist.segnum = 0; playlist.abnum = -1; } } } id = (int)playlist.ablist[playlist.abnum]; } } set_panel_int(Abtool_win->seg_text, PANEL_VALUE, playlist.segnum);/* Start playing if id is valid */ if (id > 0) { if (islower(id)) id = toupper(id); cp = strchr(idchar, id); id = cp ? cp - idchar : -1; abp_start_play(id, playlist.segnum); }}stop_play(){ playlist.abnum = -1; /* Don't start any new segments */ if (playlist.seginc != 0) /* If stepping through segments, reset to 0 */ set_panel_int(Abtool_win->seg_text, PANEL_VALUE, 0); abp_abort_play(); if (xv_get(Abtool_pwin->audio_hold, PANEL_VALUE)) abp_close_device();}/* * Notify callback function for 'delay', 'gain' text items. */Panel_settingalign_notify(Panel_item item, Event *event){ set_align(align_id); show_align(align_id); return panel_text_notify(item, event);}show_align(int n){ struct abfile *f; align_id = -1; if (strlen(filename[n]) <= (size_t)0) return; align_id = n; set_label_char(Abtool_pwin->file, idchar[n]); f = abp_get_abfile(n); set_panel_dbl(Abtool_pwin->corr,PANEL_LABEL_STRING,"%6.3f", f->p.corr); set_panel_int(Abtool_pwin->delay, PANEL_VALUE, nint(1000*f->p.delay)); set_panel_dbl(Abtool_pwin->gain, PANEL_VALUE, "%5.2f", f->p.scale);}set_align(int n){ int nd, nf; struct abfile *f; if (strlen(filename[n]) <= (size_t)0 || n != align_id) return; f = abp_get_abfile(n); nf = nint(1000 * f->p.delay); nd = get_value_int(Abtool_pwin->delay); if (nf != nd) abp_align(n, .001*nd, 0.0);}intget_segnum(){ int segnum; segnum = MAX(0, get_value_int(Abtool_win->seg_text)); return set_panel_int(Abtool_win->seg_text, PANEL_VALUE, segnum);}intget_value_int(Xv_opaque item){ int n; if (sscanf((char *)xv_get(item, PANEL_VALUE), "%d", &n) < 1) n = 0; return n;}doubleget_value_double(Xv_opaque item){ float f; if (sscanf((char *)xv_get(item, PANEL_VALUE), "%f", &f) < 1) f = 0.0; return f;}set_panel_int(Xv_opaque item, int type, int n){ char str[20]; sprintf(str, "%d", n); xv_set(item, type, str, 0); return n;}doubleset_panel_dbl(Xv_opaque item, int type, char *fmt, double f){ char str[20]; sprintf(str, fmt, f); xv_set(item, type, str, 0); return f;}voidset_label_char(Xv_opaque item, char chr){ char str[2]; str[0] = chr; str[1] = 0; xv_set(item, PANEL_LABEL_STRING, str, NULL);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -