📄 xedit_data.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) 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 * Checked by: * Revised by: Alan Parker, David Talkin * * Brief description: * *//* xedit_data.c *//* The beginnings of a waveform data editor for waves. Two editing domains are supported: (1) modification of existing signals by changing vector element values by "drawing" with the mouse; (2) cutting and splicing waveform fragments. The first domain is well developed for all vector signals; the second is under development... */static char *sccs_id = "@(#)xedit_data.c 1.11 9/28/98 ATT/ESI/ERL";#include <Objects.h>#include <spectrogram.h>#include <esps/esps.h>#include <esps/fea.h>#include <esps/limits.h>Header *dup_header();char *get_date();void free_signal();double assign_value(), get_displayed_value(), signal_get_value();extern void set_pvd();/*********************************************************************/#define y_to_val(v,y,chan) (((v)->y_offset[chan] - (y)) * (v)->y_scale[chan]/PIX_PER_CM)#undef MIN#define MIN(a,b) ( ((a)<(b)) ? (a) : (b) ) #undef MAX#define MAX(a,b) ( ((a)>(b)) ? (a) : (b) ) /*********************************************************************//* In situ modification of data element values for all types of vector signals. If a signal is modified, ".ed" is appended to its filename and it is marked to be saved. The channel (element) to be modified is determined when the button is first pressed in the window. Mouse movements with button depressed reassign data values. Button release optionally causes the display to be redrawn to reflect the changes.*/void e_modify_signal(canvas, event, arg) Canvas canvas; Event *event; caddr_t arg;{ View *v; Signal *s; static double time; static int x, y, active = -1, indo = -1, dactive = -1; int ind, id, color, type; double val; register int nf, nfs; Xv_Cursor cursor; Pixwin *pw; Rect *rect; v = (View *)xv_get(canvas, WIN_CLIENT_DATA); s = v->sig;/* Is it a regular VECTOR_SIGNAL? */ if(IS_GENERIC(s->type)) { x = event_x(event); y = event_y(event); time = v->x_to_time(v,x); ind = time_to_index(s,time); /* When BUTTON IS FIRST PRESSED: */ if(((id = event_id(event)) != LOC_DRAG) && (event_is_down(event))) { active = (v->xy_to_chan)? v->xy_to_chan(v,x,y) : generic_xy_to_chan(v,x,y); dactive = view_invert_display_index(v,active); /* to save time later.. */ if(v->cursor_plot) v->cursor_plot(v, CURSOR_COLOR); return; } /* If MOVEMENT WITH BUTTON PRESSED: */ if((active >= 0) && (id == LOC_DRAG)) { color = YA1_COLOR; /* WHAT IF IT IS NOT ALL IN MEMORY?!?!?!?! */ if((s->file != SIG_NEW) && !check_file_name(s,".ed")) { /* (new) edited signal saved on exit */ update_hdr_for_mod(s); } close_sig_file(s); s->file = SIG_NEW; /* indicate a modified signal */ val = y_to_val(v,y,dactive); /* retrieve virtual data value at cursor*/ assign_value(s, v, active, ind, val); fill_in(s, v, active, val, indo, ind); pw = canvas_pixwin(v->canvas); rect = (struct rect*)xv_get(v->canvas, WIN_RECT); pw_vector((Xv_opaque)pw,x-1,y,x+1,y,PIX_SRC|PIX_COLOR(color),color); v->cursor_time = time; if(v->y_print) v->y_print(v); indo = ind; return; } /* When BUTTON IS RELEASED: */ if (event_is_up(event) && (id != LOC_WINENTER) && (id != LOC_WINEXIT) && (id != LOC_MOVE)) { if((active >= 0) && v->redraw_on_release) redoit(v->canvas); else if (v->cursor_plot) v->cursor_plot(v, CURSOR_COLOR); /* Optionally, save the signal after each edit. */ if(v->rewrite_after_edit && (v->sig->file_size == v->sig->buff_size)) { if(v->sig->file == SIG_NEW) put_waves_signal(v->sig); else put_signal(v->sig); } active = -1; indo = -1; } return; } return;}/*********************************************************************//* Given the Signal s, represented in View v, modify displayed element chan at index ind to the new value val. The old value is returned by this function. */double assign_value(s, v, chan, ind, val) Signal *s; View *v; int ind, chan; double val;{ if(s && v && s->data && ind >= 0) { double oldv; switch(s->type & VECTOR_SIGNALS) { case P_SHORTS: { short *s_data = ((short **) s->data)[chan]; if (!s_data) return 0.0; oldv = s_data[ind]; s_data[ind] = ROUND(val); } break; case P_INTS: { int *s_data = ((int **) s->data)[chan]; if (!s_data) return 0.0; oldv = s_data[ind]; s_data[ind] = ROUND(val); } break; case P_DOUBLES: { double *s_data = ((double **) s->data)[chan]; if (!s_data) return 0.0; oldv = s_data[ind]; s_data[ind] = val; } break; case P_CHARS: { char *s_data = ((char **) s->data)[chan]; if (!s_data) return 0.0; oldv = s_data[ind]; s_data[ind] = ROUND(val); } break; case P_FLOATS: { float *s_data = ((float **) s->data)[chan]; if (!s_data) return 0.0; oldv = s_data[ind]; s_data[ind] = val; } break; case P_MIXED: { int s_type = s->types[chan]; caddr_t s_data = ((caddr_t *) s->data)[chan]; if (!s_data) return 0.0; switch (s_type) { case P_SHORTS: oldv = ((short *) s_data)[ind]; ((short *) s_data)[ind] = ROUND(val); break; case P_INTS: oldv = ((int *) s_data)[ind]; ((int *) s_data)[ind] = ROUND(val); break; case P_DOUBLES: oldv = ((double *) s_data)[ind]; ((double *) s_data)[ind] = val; break; case P_CHARS: oldv = ((char *) s_data)[ind]; ((char *) s_data)[ind] = ROUND(val); break; case P_FLOATS: oldv = ((float *) s_data)[ind]; ((float *) s_data)[ind] = val; break; default: return(0.0); } } break; default: return(0.0); } return(oldv); } return(0.0);}/*********************************************************************//* Given the Signal s, retrieve element chan at index ind. */double signal_get_value(s, chan, ind) Signal *s; int ind, chan;{ if(s && s->data && ind >= 0) { double val; if(chan >= s->dim) chan = s->dim - 1; else if(chan < 0) chan = 0; switch(s->type & VECTOR_SIGNALS) { case P_SHORTS: { short *s_data = ((short**)(s->data))[chan]; if (!s_data) return 0.0; val = s_data[ind]; } break; case P_INTS: { int *s_data = ((int**)(s->data))[chan]; if (!s_data) return 0.0; val = s_data[ind]; } break; case P_DOUBLES: { double *s_data = ((double**)(s->data))[chan]; if (!s_data) return 0.0; val = s_data[ind]; } break; case P_CHARS: { char *s_data = ((char**)(s->data))[chan]; if (!s_data) return 0.0; val = s_data[ind]; } break; case P_FLOATS: { float *s_data = ((float**)(s->data))[chan]; if (!s_data) return 0.0; val = s_data[ind]; } break; case P_MIXED: { int s_type = s->types[chan]; caddr_t s_data = ((caddr_t *)(s->data))[chan]; switch (s_type) { case P_SHORTS: val = ((short *) s_data)[ind]; break; case P_INTS: val = ((int *) s_data)[ind]; break; case P_DOUBLES: val = ((double *) s_data)[ind]; break; case P_CHARS: val = ((char *) s_data)[ind]; break; case P_FLOATS: val = ((float *) s_data)[ind]; break; default: return(0.0); } } break; default: return(0.0); } return(val); } return(0.0);}/*********************************************************************//* Given the Signal s, represented in View v, retrieve displayed element chan at index ind. */double get_displayed_value(s, v, chan, ind) Signal *s; View *v; int ind, chan;{ if(s && v) { if(chan >= v->dims) chan = v->dims - 1; else if(chan < 0) chan = 0; return(signal_get_value(s, v->elements[chan], ind)); } else return(0.0);} /*********************************************************************//* Interpolate any skipped frames. For channel chan in Signal s, shown in View v; interpolate from the value with index indo to the value val at index ind. Intermediate samples are linearly interpolated.*/fill_in(s, v, chan, val, indo, ind) Signal *s; View *v; double val; int chan, indo, ind;{ if(s && v) { double valf, valo, dv; int j, k, nf, nfs; if((indo >= 0) && ((nf = iabs((nfs = indo - ind))) > 1)) { valo = signal_get_value(s, chan, indo); if(nfs > 0) { dv = ((double)(valo-val))/nf; valf = val; k = ind; } else { dv = ((double)(val-valo))/nf; valf = valo; k = indo; } for(j=1 ; j < nf; j++) { /* Interpolate. */ valf += dv; assign_value(s, v, chan, j+k, valf); } } }}/*********************************************************************//* * The following routines permit modification or generation of signals * by cutting and pasting waveform segments. *//*********************************************************************//********************************************************************* Segment selection: Segments are selected by positioning the left and right markers using mouse buttons in either "up/down" or "move closest" mode. Operations on selected segments: Save in file; delete; (eventually expand; contract {by either interpolation or delete/iterate}). Filename selection: Four modes: (1) explicit name type-in; (2) auto-increment of numeric part of filename; (3) names read from a file-list file; (4) mktemp filenames based on the name of the signal from which the segment was excised. In all cases a brouseable list of these file names will be maintained, with mouse selection of any list element for: D/A playback; insertion into another signal; header printout; deletion; removal from the list.*//*******************************************************************/element_size(s, i) register Signal *s; int i;{ if(s) switch(s->type & VECTOR_SIGNALS) { case P_INTS: case P_UINTS: return(sizeof(int)); case P_SHORTS: case P_USHORTS: return(sizeof(short)); case P_CHARS: case P_UCHARS: return(sizeof(char)); case P_FLOATS: return(sizeof(float)); case P_DOUBLES: return(sizeof(double)); case P_MIXED: switch (s->types[i]) { case P_INTS: case P_UINTS: return(sizeof(int)); case P_SHORTS: case P_USHORTS: return(sizeof(short)); case P_CHARS: case P_UCHARS: return(sizeof(char)); case P_FLOATS: return(sizeof(float)); case P_DOUBLES: return(sizeof(double)); } default: sprintf(notice_msg, "Unknown VECTOR_SIGNAL in element_size(%x, %d)\n", s->type, i); show_notice(1,notice_msg); } return(0);}/*******************************************************************/intsamp_size(s) Signal *s;{ int i; int size = 0; for (i = 0; i < s->dim; i++) size += element_size(s, i); return size;}/*******************************************************************/add_to_new_files_browser(realname) char *realname;{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -