📄 xspect.c
字号:
/* * This material contains unpublished, proprietary software of Entropic * Research Laboratory, Inc. Any reproduction, distribution, or publication * of this work must be authorized in writing by Entropic Research * Laboratory, Inc., and must bear the notice: * * "Copyright (c) 1987-1990 AT&T, Inc. "Copyright (c) 1986-1990 Entropic * Speech, Inc. "Copyright (c) 1990-1996 Entropic Research Laboratory, Inc. * All rights reserved" * * The copyright notice above does not evidence any actual or intended * publication of this source code. * * Written by: David Talkin (AT&T) Checked by: Revised by: Rod Johnson, Alan * Parker, John Shore (ERL) * * xspect.c computation and display of spectrograms */static char *sccs_id = "@(#)xspect.c 1.32 9/28/98 ERL";#include <xview/cms.h>#include <xview/font.h>#include <sys/ioctl.h>#include <esps/esps.h>#include <esps/feaspec.h>#include <esps/unix.h>#include <esps/window.h>#include <Objects.h>#include <dsp32.h>#include <spectrogram.h>#include <dsplock.h>#include <esps/exview.h>#include <Xp_pw.h>#define _NO_PROTO#include <Xp.h>#include <XpMacros.h>/* #include <X11/Xutil.h> */#define ALWAYS_LOAD 1#define LOAD_AS_NEEDED 2#define BW_OVERLAYS 1#define HI_SPECT_LIM (127 - 22)/* * This fudge factor of 22 is to translate the image_clip semantics for * monochrome dither to a reasonable value for color/greyscale. Without this * fudge factor, all image_clip entries in various environments worldwide * would need to be changed!) */extern double log ();extern S_bar *new_scrollbar ();extern void repaint ();extern void set_pvd ();extern int run_esps_prog ();extern char *mk_esps_temp ();extern double nonlin_y_to_yval ();extern int nonlin_yval_to_y ();extern int debug_level, cmap_depth;extern Visual *visual_ptr;extern char sgram_program[];extern int dsp32_wait;extern int use_dsp32, dsp_type;extern int invert_dither; /* inverse video in dithered spectrograms? */extern Xv_Font def_font;extern int def_font_height, def_font_width;extern int menu_item_key; /* key for storing last selected menu item as * XV_KEY_DATA for canvas. */extern int new_width, /* dimensions of new window made by */ new_height; /* make command */char spect_prog[100] = "";static int use_spect_prog = 0; /* 0 = do not use dsp_prog_name from * params file; 1 = means do use it. * This is so that we can wire in a * path for each type of DSP */extern int use_static_cmap;extern Frame daddy;double image_clip = 7.0, image_range = 40.0;extern char wb_spect_params[], nb_spect_params[];char *spect_params = wb_spect_params;extern int next_x, next_y, w_y_incr, w_x_incr, da_done;extern int scrollbar_height, readout_bar_height;char loaded[100];extern short dsp_is_open;extern char *dspmap ();char *inc_esps_name ();char *sh_mem;char *savestring ();static void set_spect_scale ();static int interp ();Menu make_spect_menu ();extern Menu spect_menu;void cmap_spect ();extern void e_play_between_marks (), e_play_window (), e_play_file (), e_play_from_cursor (), e_page_ahead (), e_page_back (), e_align_views (), e_position_view (), e_zoom_in (), e_zoom_out (), e_wb_spectrogram (), e_nb_spectrogram (), e_output_bitmap (), e_save_segment (), e_delete_segment (), e_insert_file (), e_kill (), e_forward_window (), e_backward_window (), e_repeat_previous (), e_zoom_full_out (), e_blow_up (), e_blow_up_call_function (), e_up_down_move_marks (), e_move_closest_mark (), e_modify_signal (), m_play_file (), e_reassign_formant (), e_modify_intensity (), e_move_contour (), menu_operate (), c_print_graphic (), e_print_ensemble ();static Menuop srbo16 ={"print ensemble", e_print_ensemble, NULL, NULL}, srbo15 ={"print graphic", c_print_graphic, NULL, &srbo16}, srbo14 ={"kill window", e_kill, NULL, &srbo15}, srbo13 ={"insert file", e_insert_file, NULL, &srbo14}, srbo12 ={"delete segment", e_delete_segment, NULL, &srbo13}, srbo11 ={"save segment in file", e_save_segment, NULL, &srbo12}, srbo8 ={"zoom full out", e_zoom_full_out, NULL, &srbo11}, srbo7 ={"zoom out", e_zoom_out, NULL, &srbo8}, srbo6b ={"zoom in", e_zoom_in, NULL, &srbo7}, srbo6 ={"bracket markers", e_position_view, NULL, &srbo6b}, srbo5c ={"align & rescale", e_align_views, NULL, &srbo6}, srbo5b ={"window back", e_backward_window, NULL, &srbo5c}, srbo5a ={"window ahead", e_forward_window, NULL, &srbo5b}, srbo5 ={"page back", e_page_back, NULL, &srbo5a}, srbo4 ={"page ahead", e_page_ahead, NULL, &srbo5}, srbo3 ={"play to end of file", e_play_from_cursor, NULL, &srbo4}, srbo2 ={"play entire file", e_play_file, NULL, &srbo3}, srbo1 ={"play window contents", e_play_window, NULL, &srbo2};Menuopright_sbut_menu ={ "play between marks", e_play_between_marks, NULL, &srbo1},spect_operators ={ "repeat previous", e_repeat_previous, NULL, &right_sbut_menu};/* * The following menu ops. are used by left and middle buttons of spectrogram * windows. The arguments for the called routines are (canvas,event,arg). */Menuopslbo3 ={ "mark formants", e_reassign_formant, NULL, &spect_operators},slbo2 ={ "move closest", e_move_closest_mark, NULL, &slbo3},def_aux_ops_bws ={ "up/down move", e_up_down_move_marks, NULL, &slbo2},smbo3 ={ "move contour", e_move_contour, NULL, &def_aux_ops_bws},def_aux_sbut_ops ={ "modify intensity", e_modify_intensity, NULL, &smbo3};Menuop *aux_sbut_ops = &def_aux_sbut_ops;extern char def_smiddle_op[], def_move_op[];extern char def_sleft_op[];void (*right_sbutton_proc) () = menu_operate;int wind_type = 3;extern int doing_print_graphic, print_only_plot;Display *get_xp_display ();int bits_per_pixel;/*************************************************************************/#if defined(SUN4) || defined(HP700) || defined(SG)#define CLIENT_BYTE_ORDER MSBFirst#endif#if defined(LINUX) || defined(DEC_ALPHA)#define CLIENT_BYTE_ORDER LSBFirst#endif/*************************************************************************/static intrev (i, bits) int i; int bits;{ int rev_i = i; switch (bits) { case 8: rev_i = ((rev_i & 0xf0) >> 4) | ((rev_i & 0x0f) << 4); case 4: rev_i = ((rev_i & 0xcc) >> 2) | ((rev_i & 0x33) << 2); case 2: rev_i = ((rev_i & 0xaa) >> 1) | ((rev_i & 0x55) << 1); break; default: spsassert (0, "error in call to rev (bits)"); } return rev_i;}static voidbit_reverse (buffer, num_read) char *buffer; int num_read;{ int i; for (i = 0; i < num_read; i++) { buffer[i] = rev (buffer[i], 8); }}static intbyte_swap (t) int t;{ char tmp; union { int l_val; char byte[4]; } u2; u2.l_val = t; tmp = u2.byte[0]; u2.byte[0] = u2.byte[3]; u2.byte[3] = tmp; tmp = u2.byte[1]; u2.byte[1] = u2.byte[2]; u2.byte[2] = tmp; return u2.l_val;}static voidbyte_swap_s (s) short *s;{ char tmp; union { short s_val; char byte[2]; } u2; u2.s_val = *s; tmp = u2.byte[0]; u2.byte[0] = u2.byte[1]; u2.byte[1] = tmp; *s = u2.s_val;}/*************************************************************************/Menuop *spect_get_ops (){ return (&spect_operators);}/*************************************************************************/Spectrogram *new_spectrogram (sig) Signal *sig;{ Spectrogram *spect; if (!(spect = (Spectrogram *) malloc (sizeof (Spectrogram)))) { return (NULL); } if (sig) { spect->start_time = BUF_START_TIME (sig); spect->end_time = BUF_END_TIME (sig); } else { spect->start_time = 0.0; spect->end_time = 0.0; } spect->sig = sig; /* original signal */ if (sig->name && *(sig->name)) { spect->signame = malloc (strlen (sig->name) + 1); strcpy (spect->signame, sig->name); } else spect->signame = NULL; spect->outname = NULL; spect->sigfreq = sig->freq; if (!get_spgm_params (spect_params, spect)) { sprintf (notice_msg, "Problems reading spectrogram parameter file %s.", spect_params); show_notice (1, notice_msg); free ((char *) spect); return (NULL); } return (spect);}/*************************************************************************/get_spgm_params (name, sp) char *name; Spectrogram *sp;{ FILE *fdp, *fopen (); char *param_file; int i, j; char in[501], *full_path (), *apply_waves_input_path (); double freq; static double wsize = 6.4, wstep = 2.0, qstep = 1.0, thresh = 35.0, agc = .55, var = 0.0, preemp = -1.0; static int nfft = 128, yinterp = 4, xdith = 0, ydith = 0; static int dix = 3, diy = 11; /* default spatial filter dimensions */ static double di_filt[] = {1., 1.5, 2., 3., 4., 5., 4., 3., 2., 1.5, 1., 2., 3., 4., 6., 8., 10., 8., 6., 4., 3., 2., 4., 6., 8., 12., 16., 1., 0., 0., 0., 0., 0.}; static Selector a14 = {"use_dsp_prog_name", "%d", (char *) &use_spect_prog, NULL}, a13 = {"window_type", "%d", (char *) &wind_type, &a14}, a12 = {"dsp_prog_name", "%s", spect_prog, &a13}, a11 = {"win_size_ms", "%lf", (char *) &wsize, &a12}, a10 = {"win_step_ms", "%lf", (char *) &wstep, &a11}, a9 = {"ampl_scale", "%lf", (char *) &qstep, &a10}, a8 = {"ampl_offset_db", "%lf", (char *) &thresh, &a9}, a7 = {"agc_ratio", "%lf", (char *) &agc, &a8}, a6 = {"var_norm", "%lf", (char *) &var, &a7}, a5 = {"fft_points", "%d", (char *) &nfft, &a6}, a4 = {"freq_intrp", "%d", (char *) &yinterp, &a5}, a3 = {"preemp", "%lf", (char *) &preemp, &a4}, a2 = {"x_dither", "%d", (char *) &xdith, &a3}, a1 = {"y_dither", "%d", (char *) &ydith, &a2}; xdith = ydith = 0; param_file = apply_waves_input_path (NULL, name); if (!(fdp = fopen (param_file, "r"))) { char *tmp_name; tmp_name = find_esps_file (NULL, "wb_params", "$ESPS_BASE/lib/waves/files", NULL); fdp = fopen (tmp_name, "r"); if (fdp) { sprintf (notice_msg, "Can't find readable spectrogram parameter file %s.\nUsed %s.", name, tmp_name); show_notice (0, notice_msg); } free (tmp_name); } free (param_file); if (fdp) { while (fgets (in, 500, fdp) && (*in != '*')) if ((*in != '#') && (*in != '\n')) /* ignore empty lines and comments */ get_args (in, &a1); if (xdith && ydith) { sp->dimp = (double *) malloc (sizeof (double) * xdith * ydith); for (i = 0; i < xdith; i++) { for (j = 0; j < ydith; j++) fscanf (fdp, "%lf ", &sp->dimp[(i * ydith) + j]); } } fclose (fdp); } else { sprintf (notice_msg, "%s %s\n%s\n%s", "Can't find readable spectrogram parameter file", name, "or default file $ESPS_BASE/lib/waves/files/wb_params.", "Using default (compiled-in) parameters."); show_notice (0, notice_msg); } if (!(xdith && ydith)) { xdith = dix; ydith = diy; sp->dimp = (double *) malloc (sizeof (double) * (j = xdith * ydith)); for (i = 0; i < j; i++) sp->dimp[i] = di_filt[i]; } sp->xdith = xdith; sp->ydith = ydith; if ((wind_type < 0) || (wind_type > 9)) { sprintf (notice_msg, "Bad window type (%d) in get_spgm_params.", wind_type); show_notice (1, notice_msg); return (0); } sp->window_type = wind_type; sp->window_size = wsize; sp->window_step = wstep; sp->q_step = qstep; sp->q_thresh = thresh - 40; /* (for compatability with old .wave_pro * files) */ sp->agc_ratio = agc; sp->preemp = preemp; sp->var_ratio = var; if (!yinterp) yinterp = 1; sp->yinterp = yinterp; if (nfft > 1024) { show_notice (0, "Max fft size available is 1024 points; limiting accordingly."); nfft = 1024; } sp->nfft = nfft; sp->bitmap = XV_NULL; /* convert ms to seconds and integerize the time step and size */ if (sp->sig && (sp->sig->freq > 0.0)) freq = sp->sig->freq; else freq = 10000.; /* what else can one do? */ i = 0.5 + (freq * sp->window_step / 1000.); if (!i) { sprintf (notice_msg, "Window step (%fms) too small in get_spgm_params().", sp->window_step); show_notice (1, notice_msg); return (FALSE); } sp->window_step = ((double) i) / freq; /* install actual step size * implemented */ if ((sp->yinterp * sp->nfft / 2) > SCREEN_HEIGHT) { /* pixels vertically... */ sprintf (notice_msg, "%s\n%s %d\n%s", "Specified vertical size too large.", "Limiting to <=", SCREEN_HEIGHT, "(or put the monitor on its side)."); show_notice (0, notice_msg); sp->yinterp = 2 * SCREEN_HEIGHT / sp->nfft; } i = 0.5 + (freq * sp->window_size / 1000.); if (i < 4) { sprintf (notice_msg, "Window size (%fms) too small in get_spgm_params().", sp->window_size); show_notice (1, notice_msg); return (FALSE); } while (i > sp->nfft) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -