📄 xedit_data.c
字号:
extern Pending_input new_files; /* Put the new file at the head of the list and "activate" it for display purposes. */ if(new_files.list) ((Menu_list*)new_files.list)->active = FALSE; if(add_to_menu_list(&new_files.list, realname)) ((Menu_list*)new_files.list)->active = TRUE; if(new_files.canvas) menu_redoit(new_files.canvas, NULL, NULL);}/*******************************************************************/save_segment(s,start_time,duration) Signal *s; double start_time, duration;{ char *ext, *name, next[200], realname[200], *cp; extern int dont_save_sgrams; extern char outputname[]; if (((s->type & SPECIAL_SIGNALS) == SIG_SPECTROGRAM) && dont_save_sgrams) return(TRUE); if(!make_edited_filename(s,realname)) return(FALSE); /* * Might want to put in a check here for existing files and/or previously * used names. At this point, ``realname'' has been set by by some means. */ if(save_seg_in_file(s, start_time, duration, realname)) { add_to_new_files_browser(realname); return(TRUE); } else show_notice(1,"Problems in save_seg_in_file in save_segment");}/*********************************************************************/do_deletions(v,start,end) View *v; double start, end;{ double dt; Signal *s = v->sig; char newname[256]; if (v->sig->file != SIG_NEW) insert_numeric_ext(v->sig->name,++v->sig->version,newname); else *newname = '\0'; if (delete_segment(s, start, end, newname)) { if(*newname) update_window_titles(v->sig); v->rmarker_time = v->lmarker_time; if(v->start_time < (dt = BUF_START_TIME(v->sig))) { v->start_time = dt; view_fit_duration(v); } if(ET(v) > (dt = BUF_END_TIME(v->sig))) view_fit_duration(v); redoit(v->canvas); }}#define RETURN(val,msg) \ { if(msg) fprintf(stderr,"save_seg_in_file: %s\n",msg); return(val); }/*******************************************************************/save_generic_seg(s, start_time, duration, file) Signal *s; double start_time, duration; char *file;{ Signal *so; char comment[200]; char **dpp, **dppi; int n, i, j, size; double etr, ets; if(!((start_time >= s->start_time) && ((etr = start_time+duration) <= (ets = (s->start_time + SIG_DURATION(s)))))) { if((start_time >= ets) || (etr <= s->start_time)) { printf("Bogus times passed to save_seg_in_file(%s %f %f)\n", s->name, start_time, duration); return(FALSE); } if(start_time < s->start_time) start_time = s->start_time; if(ets < etr) etr = ets; duration = etr - start_time; sprintf(notice_msg, "Limits requested in save_seg_in_file exceeded signal limits.\nAdjusted to: start_time=%lf duration=%lf",start_time,duration); show_notice(1,notice_msg); } n = 0.5 + s->freq * duration; if((so=new_signal(file, SIG_NEW, dup_header(s->header), (caddr_t) NULL, n, s->freq, s->dim))) { sprintf(comment,"save_seg_in_file: start_time %f duration %f signal %s", start_time, duration, s->name); clone_methods(so,s); so->start_time = start_time; so->file_size = n; so->end_time = BUF_END_TIME(so); if (so->header && so->header->magic == ESPS_MAGIC && so->header->esps_hdr) { struct header *new_hdr; new_hdr = copy_header(so->header->esps_hdr); so->header->esps_hdr = new_hdr; set_pvd(new_hdr); add_comment(new_hdr, "xwaves "); strcat(comment, "\n"); add_comment(new_hdr, comment); *(genhd_type("start_time", (int *) NULL, new_hdr) == DOUBLE ? get_genhd_d("start_time", new_hdr) : add_genhd_d("start_time", (double *) NULL, 1, new_hdr) ) = start_time; *(genhd_type("end_time", (int *) NULL, new_hdr) == DOUBLE ? get_genhd_d("end_time", new_hdr) : add_genhd_d("end_time", (double *) NULL, 1, new_hdr) ) = so->end_time; } if((BUF_START_TIME(s) <= start_time) && (BUF_END_TIME(s) >= (start_time + duration))) { /* it's all in memory */ if(!(so->data = (caddr_t)(dpp = (char**)malloc(sizeof(char*) * s->dim)))) { printf("Allocation problems in save_seg_in_file()\n"); free_signal(so); return(FALSE); } i = time_to_index(s,start_time); dppi = (char**)(s->data); for(j=0; j < s->dim; j++) /* new pointer array for signal subsegment */ dpp[j] = dppi[j] + element_size(s, j) * i; so->start_samp = 0; if(s->x_dat) so->x_dat = &(s->x_dat[i]); get_maxmin(so); head_printf(so->header,"operation",comment); head_printf(so->header,"samples", (char *) &n); head_printf(so->header,"version", (char *) &(so->version)); head_printf(so->header,"start_time", (char *) &start_time); head_printf(so->header,"end_time", (char *) &(so->end_time)); head_printf(so->header,"maximum", (char *) &(*so->smax)); head_printf(so->header,"minimum",(char *) &(*so->smin)); head_printf(so->header,"time",get_date()); if(!(i = put_signal(so))) printf("put_signal() problems in save_seg_in_file()\n"); free(so->data); so->data = NULL; so->x_dat = NULL; free_signal(so); return(i); } else { /* must do read/write transfers */ extern int max_buff_bytes; /* defined in globals.c */ double chunk, ts, dur, amax, amin, tstep, st; int bsize; chunk = ((double) max_buff_bytes)/(samp_size(s) * s->freq); bsize = (int)((duration < chunk)? duration * s->freq : chunk * s->freq); tstep = ((double)bsize)/s->freq; /* First, read over the data and find max and min. */ for(amax = *s->smin, amin = *s->smax, dur=duration, ts=tstep, st=start_time ; dur > 0; dur -= ts, st += ts) { if(ts > dur) ts = dur; if(ts > 0.5/so->freq) { /* more than 1/2 sample interval? */ if(read_data(s,st,ts)) { get_maxmin(s); if(*s->smin < amin) amin = *s->smin; if(*s->smax > amax) amax = *s->smax; } else { printf("read_data() error in save_seg_in_file()\n"); return(FALSE); } } } head_printf(so->header,"operation",comment); head_printf(so->header,"samples", (char *) &n); head_printf(so->header,"version", (char *) &(so->version)); head_printf(so->header,"start_time", (char *) &start_time); head_printf(so->header,"end_time", (char *) &(so->end_time)); head_printf(so->header,"maximum", (char *) &amax); head_printf(so->header,"minimum", (char *) &amin); head_printf(so->header,"time",get_date()); if(!output_header(so)) { printf("Problems with header or file open in save_seg_in_file()\n"); return(FALSE); } /* Now do the real read/write transfers. */ for(so->start_samp = 0, so->buff_size = bsize, dur=duration, ts=tstep ; dur > 0; dur -= ts, start_time += ts) { if(ts > dur) ts = dur; if(ts > 0.5/so->freq) { /* more than 1/2 sample interval? */ if(read_data(s,start_time,ts)) { so->data = s->data; so->x_dat = s->x_dat; if(so->utils->write_data(so,start_time,ts)) so->start_samp += bsize; else { printf("write_data() error in save_seg_in_file()\n"); return(FALSE); } } else { printf("read_data() error in save_seg_in_file()\n"); return(FALSE); } } } so->data = NULL; /* NOTE: so->data was == s->data (don't free)*/ so->x_dat = NULL; free_signal(so); if(s->views) read_data(s,s->views->start_time, ET(s->views) - s->views->start_time); close_sig_file(s); return(TRUE); } } else show_notice(1,"Can't create a scratch buffer signal in save_seg_in_file"); return(FALSE);}/*******************************************************************/save_seg_in_file(s, start_time, duration, file) Signal *s; double start_time, duration; char *file;{ Signal *so; char comment[200]; char **dpp, **dppi; int n, i, j; if(IS_TAGGED_FEA(s)) return(tag_save_seg(s, start_time, duration, file)); if(s && (duration > 0.0)) { if (IS_GENERIC(s->type)) return(save_generic_seg(s, start_time, duration, file)); } sprintf(notice_msg, "Bad signal type (%x) or duration (%f) in save_seg_in_file()\n", ((s)? s->type : 0), duration); show_notice(1,notice_msg); return(FALSE);}#undef RETURN /*******************************************************************/delete_generic_segment(s, start_time, end_time, newname) Signal *s; double start_time, end_time; char *newname;{#define MOVE_TYPES(type_1, type_2) { \ type_1 *dpp = (type_1 *) s->data; \ type_2 *dp = (type_2 *) dpp[dim]; \ register type_2 *p, *q, *r; \ if (!dp) { \ show_notice(1, "NULL data array in delete_segment."); \ return FALSE; \ } \ for (p = dp+is, q = dp+ie+1, r = dp+s->buff_size; q < r; ) \ *p++ = *q++; \ dpp[dim] = (type_1) realloc((char *) dp, new_size * sizeof(type_2)); \ } int new_size, is, ie, dim; char comment[200]; struct header *hdr; if((start_time < end_time) && (start_time >= s->start_time) && (end_time <= (s->start_time + ((double)s->file_size)/s->freq))) { if (!s->data) { show_notice(1, "NULL data array pointer in delete_segment."); return FALSE; } if(s->buff_size == s->file_size) { /* it's all in memory */ is = time_to_index(s,start_time); ie = time_to_index(s,end_time); new_size = s->buff_size - (ie - is + 1); if(new_size <= 0) { show_notice(1,"Edited signal would have zero length; no op performed."); return(FALSE); } if (s->file != SIG_NEW) rename_signal(s, newname); for(dim=0; dim < s->dim; dim++) { switch(s->type & VECTOR_SIGNALS) { case P_SHORTS: case P_USHORTS: MOVE_TYPES(short *, short); break; case P_INTS: case P_UINTS: MOVE_TYPES(int *, int); break; case P_FLOATS: MOVE_TYPES(float *, float); break; case P_DOUBLES: MOVE_TYPES(double *, double); break; case P_CHARS: case P_UCHARS: MOVE_TYPES(char *, char); break; case P_MIXED: switch (s->types[dim]) { case P_SHORTS: case P_USHORTS: MOVE_TYPES(caddr_t, short); break; case P_INTS: case P_UINTS: MOVE_TYPES(caddr_t, int); break; case P_FLOATS: MOVE_TYPES(caddr_t, float); break; case P_DOUBLES: MOVE_TYPES(caddr_t, double); break; case P_CHARS: case P_UCHARS: MOVE_TYPES(caddr_t, char); break; default: sprintf(notice_msg,"Bad data type (%x) in delete_segment", s->types[dim]); show_notice(1,notice_msg); return(FALSE); } break; default: sprintf(notice_msg, "Bad data type (%x) in delete_segment()\n",s->type); show_notice(1,notice_msg); return(FALSE); } } s->buff_size = s->file_size = new_size; sprintf(comment,"delete_segment: start_time %f end_time %f signal %s", start_time, end_time, s->name); head_printf(s->header,"operation",comment); head_printf(s->header,"samples",(char*)&new_size); head_printf(s->header,"version", (char *) &(s->version)); if (!is) { /* deleted leading segment */ s->start_time += ((double)(ie+1))/s->freq; head_printf(s->header,"start_time",(char*)&s->start_time); } s->end_time = BUF_END_TIME(s); head_printf(s->header,"end_time", (char *) &(s->end_time)); get_maxmin(s); head_printf(s->header,"maximum", (char *) &(*s->smax)); head_printf(s->header,"minimum", (char *) &(*s->smin)); head_printf(s->header,"time",get_date()); if (s->header && s->header->magic == ESPS_MAGIC && (hdr = s->header->esps_hdr)) { strcat(comment, "\n"); add_comment(hdr, comment); *(genhd_type("start_time", (int *) NULL, hdr) == DOUBLE ? get_genhd_d("start_time", hdr) : add_genhd_d("start_time", (double *) NULL, 1, hdr) ) = s->start_time; *(genhd_type("end_time", (int *) NULL, hdr) == DOUBLE ? get_genhd_d("end_time", hdr) : add_genhd_d("end_time", (double *) NULL, 1, hdr) ) = s->end_time; } return(TRUE); } else show_notice(1,"Can't handle partially buffered signals"); } else { sprintf(notice_msg, "Absurd boundary times passed to delete_segment(%f,%f)\n", start_time, end_time); show_notice(1,notice_msg); } return(FALSE);#undef MOVE_TYPES}/*******************************************************************//* Delete a segment from a signal. Create a new signal as a result (the original signal will remain unchanged). If the original signal is entirely in memory, delete the requested segment and simply mark the signal to be saved. If it is a "large" signal (i.e. not entirely in memory), perform read/writes as required to delete the signal within the memory constraints imposed by "page_size." */delete_segment(s, start_time, end_time, newname) Signal *s; double start_time, end_time; char *newname;{ if(s && IS_GENERIC(s->type)) return(delete_generic_segment(s, start_time, end_time, newname)); printf("Bad signal type in delete_segment\n."); return(FALSE);} /* 11-13-87 mcb * File Naming Schemes * Here are some facts to keep in mind when reading the commentary below: * (1) When a signal is modified (waveform redrawn with cursor), the * extension ".ed" is included in the current name as follows: * "abc" -> "abc.ed" * "abc.x" -> "abc.ed.x" * "abc.x.y.z" -> "abc.x.y.ed.z" * (2) When a segment is saved and NO OUTPUT NAME IS GIVEN, the extension * ".#<number>" is combined with the parent signal's name to form a name * for the new segment signal. <number> is a counter (separate for each * signal) that is incremented for each save operation. Extension * placement is the same as for ".ed" above, e.g. "abc.#1.x". * (3) When a segment is saved and there is an output name, things work * exactly as before (which I will not try to explain just now). * (4) When a segment is deleted, the original name will be changed according * to the rules for saving segments in (2) above, e.g. "abc.#2.x". */ /* When segments are copied from a signal to a separate file the problem of how to name the new file arises. This problem is more severe when "edit_ganged" is set and there are several elements in the display ensemble. Some possible alternatives: (1) Use the original filename made unique by mktemp(); the extension, if present, would remain the same, else, the last character would remain the same. (2) Use a simplified version of the original file name made unique by mktemp; an extension would be generated by table lookup on the file type. (3) Append incrementing digits to the filename to maintain uniqueness leaving the extension, if any, unchanged. (4) Read a basename from a list of files to be generated; maintain uniqueness with incrementing digits (or mktemp()); append extensions which indicate file type. It is desirable that all files generated by editing operations be listed and readily accessible by mousing the list. The listing window could have a menu providing the following operations on listed objects: (1) Read into and display by waves (2) Remove form list (3) Delete file (and remove form list) (4) D/A convert (possibly after synthesis), if possible A list of file objects may also be generated by the unix ls command, or reading from a file. These lists should also be manipulable as above. Each list can have a constant pathname prefix which is not repeated for each list element in the listing, but is prepended as necessary when operations are performed. A general procedure for accessing existing files could be: If a complete, correct filename corresponding to a signal is typed to a panel item, the file is accessed directly as usual. If the pathname is terminated with a "/" or a "?" the trailing "? or "/" will be removed and a listing of the corresponding path will be generated. Selection of an item from the resulting list will then cause the panel item name to be completed and the list window to be destroyed. A structure "pending_input" could be set to indicate what item is to get the selection. typedef struct pending_input { char *results_to; /* target array to be filled char *path_prefix; /* the pathname to be completed Panel_item item; /* the text item, if any, to be updated caddr_t list; /* pointer to alternatives list Canvas canvas; /* alternatives display window void (*proc)(); /* to be called with item and full name as arg. int destroy_on_select; /* boolean for window destroy char *banner; /* optional string for window label struct pending_input *next; struct pending_input *prev; } Pending_input;*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -