📄 xoverlays.c
字号:
nearest and establish that as the "working" formant. When LOC_DRAG events are detected, the POLE which is closest in time-frequency is assigned to the working formant and the FORMANTS signal is updated to reflect this. The screen displays are adjusted accordingly. */e_reassign_formant(canvas, event, arg) Canvas canvas; Event *event; caddr_t arg;{ static int active = -1, indo = -1; Signal *s, *sp = NULL, *sf = NULL, *sg = NULL; Object *o; POLE **ppp; View *v, *vh, *vsp, *vsf, *vsg; int type, id, x, y, color; register int indf, indp, i, j, k; register double time, freq, d_freq, amin, dtmp; char *cp, *ct; Pixwin *pw; Rect *rect; vh = v = (View*)xv_get(canvas, WIN_CLIENT_DATA);/* Want to accomplish the following: If no formant tracks are overlaid (.pole tracks are optional): Else, create a .fb signal with all formant frequencies set to nominal values. Overlay this signal on the spectrogram. Else, If .fb and .pole signls are overlaid, modify the .fb file by moving the nearest formant to the pole nearest the cursor. if .pole signals only are overlaid, assign current formant according to cursor location re nominal formant overlay. If .fb file is overlaid, modify nearest formant to match cursor frequency location. If the name of a file to be modified ends in .ed, overwrite it, else change its name to end in .ed and write a new file.*/ while(v) { /* try to find .pole and .fb overlay signals */ if((type = v->sig->type & SPECIAL_SIGNALS) == SIG_LPC_POLES) { sp = v->sig; vsp = v; } if(type == SIG_FORMANTS) { sf = v->sig; vsf = v; } if (type == SIG_GENERAL) { sg = v->sig; vsg = v; } if(sp && sf) { /* if both .fb and .pole exist... */ /* make cursor time an integral number of data samples*/ time = o_x_to_time(sf,vh, event_x(event)); x = o_time_to_x(vh,time) + o_off; freq = vh->y_to_yval(vh, event_y(event)); indf = vec_time_to_index(sf, time); indp = vec_time_to_index(sp, time); j = sf->dim/2;/* INITIAL BUTTON PRESS */ if(((id = event_id(event)) != LOC_DRAG) && (event_is_down(event))) { active = vsf->cursor_channel; indo = indf; /* for interpolator */ if(vh->cursor_plot) vh->cursor_plot(vh,CURSOR_COLOR); return(TRUE); }/* DRAWING ON WINDOW */ ppp = (POLE**)sp->data; if((active >= 0) && ppp && ppp[indp] && ppp[indp]->npoles && (id == LOC_DRAG)) { int nin, inc; if(vh->overlay_as_number) color = FOREGROUND_COLOR; else color = YA1_COLOR; if((sf->file != SIG_NEW) && check_file_name(sf,".ed")) { close_sig_file(sf); sf->file = SIG_NEW; } /* Find the closest "pole" (candidate) frequency. */ for(amin=fabs(freq - ppp[indp]->freq[0]),j=1,k=0; j < ppp[indp]->npoles; j++) if((dtmp = fabs(ppp[indp]->freq[j] - freq)) < amin) { amin = dtmp; k = j; } assign_value(sf, vsf, active, indf, (double)(ppp[indp]->freq[k])); assign_value(sf, vsf, (sf->dim/2) + active, indf, (double)(ppp[indp]->band[k])); if(indo >= 0) { fill_in(sf, vsf, active, (double)(ppp[indp]->freq[k]), indo, indf); fill_in(sf, vsf, (sf->dim/2) + active, (double)(ppp[indp]->band[k]), indo, indf); nin = indf - indo; } else nin = 0; indo = indf; if(nin != 0) { /* replot all points traversed */ inc = nin/iabs(nin); indp -= nin; indf -= nin; nin = iabs(nin); pw = canvas_pixwin(v->canvas); rect = (struct rect*)xv_get(v->canvas, WIN_RECT); do { indp += inc; indf += inc; time = sf->utils->index_to_time(sf, indf); x = o_time_to_x(vh,time) + o_off; for(j=0; j < ppp[indp]->npoles; j++) { y = vh->yval_to_y(vh,ppp[indp]->freq[j]) + o_off; pw_write(pw, x, y, o_siz, o_siz, PIX_SRC|PIX_COLOR(color), NULL, 0, 0); } k = vsf->dims; if(vh->overlay_as_number) { char fnum[2]; x += o_xoff - o_off; fnum[1] = 0; for(j=0; j < k; j++) { *fnum = '1' + vsf->elements[j]; y = vh->yval_to_y(vh,get_displayed_value(sf,vsf,j,indf)) + o_yoff; pw_ttext(pw, x, y, PIX_SRC|PIX_COLOR(FOREGROUND_COLOR), def_font, fnum); } } else { for(j=0; j < k; j++) { y = vh->yval_to_y(vh,get_displayed_value(sf,vsf,j,indf)) + o_off; pw_write(pw, x, y, o_siz, o_siz, PIX_SRC|PIX_COLOR(YA1_COLOR+vsf->elements[j]+1), NULL, 0, 0); } } } while(--nin > 0); } return(TRUE); }/* BUTTON RELEASED IN WINDOW?? */ if(finish_overlay_edit(sf,vh,event,active)) { active = -1; indo = -1; } return(TRUE); } /* end if(sp && sf) */ v = v->next; } /* finished searching view list for pole and formant signals */ if(sf) { /* got here because there is no sp... */ time = o_x_to_time(sf,vh, event_x(event)); x = o_time_to_x(vh,time); freq = vh->y_to_yval(vh, event_y(event)); indf = vec_time_to_index(sf, time); /* INITIAL BUTTON PRESS */ if(((id = event_id(event)) != LOC_DRAG) && (event_is_down(event))) { active = vsf->cursor_channel; if(vh->cursor_plot) vh->cursor_plot(vh, CURSOR_COLOR); return(TRUE); } /* DRAWING ON WINDOW */ if((active >= 0) && (id == LOC_DRAG)) { double val; if(sf->file != SIG_NEW) { if (check_file_name(sf,".ed")) { close_sig_file(sf); sf->file = SIG_NEW; } else if(sf->header && sf->header->magic == ESPS_MAGIC) add_comment(sf->header->esps_hdr, "xwaves modify formants\n"); } val = assign_value(sf, vsf, active, indf, freq); if(indo >= 0) fill_in(sf, vsf, active, freq, indo, indf); indo = indf; overlay_replot_value(vh, x, val, freq, active); return(TRUE); }/* BUTTON RELEASED IN WINDOW?? */ if(finish_overlay_edit(sf,vh,event,active)) { active = -1; indo = -1; } return(TRUE); } else if(sg) { /* got here because there is no formant signal (sf) */ time = o_x_to_time(sg, vh, event_x(event)); x = o_time_to_x(vh, time); freq = vh->y_to_yval(vh, event_y(event)); indf = sg->utils->time_to_index(sg, time); /* INITIAL BUTTON PRESS */ if ((id = event_id(event)) != LOC_DRAG && event_is_down(event)) { active = vsg->cursor_channel; if(vh->cursor_plot) vh->cursor_plot(vh, CURSOR_COLOR); return TRUE; } /* DRAWING ON WINDOW */ if ((active >= 0) && id == LOC_DRAG) { if (sg->file != SIG_NEW) { if (check_file_name(sg,".ed")) { close_sig_file(sg); sg->file = SIG_NEW; } else if (sg->header && sg->header->magic == ESPS_MAGIC) add_comment(sg->header->esps_hdr, "xwaves modify formants\n"); } d_freq = assign_value(sg, vsg, active, indf, freq); if(indo >= 0) fill_in(sg, vsg, active, freq, indo, indf); indo = indf; overlay_replot_value(vh, x, d_freq, freq, active); return TRUE; }/* BUTTON RELEASED IN WINDOW?? */ if(finish_overlay_edit(sg,vh,event,active)) { active = -1; indo = -1; } return(TRUE); } else { /* got here because no sf and no sg */ if(!sp) sp = vh->sig; /* use the spectrogram signal if no poles */ if((v = (View*)create_dummy_sf(sp,vh))) { sf = v->sig; time = o_x_to_time(sf,vh, event_x(event)); x = o_time_to_x(vh,time) + o_xoff; /* INITIAL BUTTON PRESS */ if(((id = event_id(event)) != LOC_DRAG) && (event_is_down(event))) { active = (v->xy_to_chan)? v->xy_to_chan(v, x, event_y(event)) : overlay_xy_to_chan(v, x, event_y(event)); if(debug_level) fprintf(stderr,"active:%d sf->dim:%d sf->type:%x\n", active,sf->dim,sf->type); if(vh->cursor_plot) vh->cursor_plot(vh, CURSOR_COLOR); return(TRUE); } } } return(FALSE);}/*******************************************************************/overlay_replot_value(vh, x, val, freq, active) View *vh; double val, freq; int x, active;{ int y; Pixwin *pw = canvas_pixwin(vh->canvas); if(vh->overlay_as_number) { /* numbers distinguish formants */ char fnum[2]; x += o_xoff; fnum[1] = 0; *fnum = '1' + active; y = vh->yval_to_y(vh,val) + o_yoff; pw_ttext(pw, x, y, PIX_SRC|PIX_COLOR(BACKGROUND_COLOR), def_font, fnum); y = vh->yval_to_y(vh,freq) + o_yoff; pw_ttext(pw, x, y, PIX_SRC|PIX_COLOR(FOREGROUND_COLOR), def_font, fnum); } else { /* use colors to distinguish formants */ x += o_off; y = vh->yval_to_y(vh,val) + o_off; pw_write(pw, x, y, o_siz, o_siz, PIX_SRC|PIX_COLOR(FOREGROUND_COLOR), NULL, 0, 0); y = vh->yval_to_y(vh,freq) + o_off; pw_write(pw, x, y, o_siz, o_siz, PIX_SRC|PIX_COLOR(YA1_COLOR+active+1), NULL, 0, 0); }}/*******************************************************************/View *create_dummy_sf(sp,vh) Signal *sp; /* a pole signal currently overlaid on a spectrogram */ View *vh; /* the spectrogram view */{ Signal *sf; View *v; int dim, i, j, k, size; double **dpp, *dp, freq, band; caddr_t *cpp; char temp[200], *cp; if(sp && vh) { dim = 2 * (1 + ((sp->band - 500)/1000)); if(dim > 8) dim = 8; if((sp->type & SPECIAL_SIGNALS) != SIG_LPC_POLES) { freq = 100.0; /* best guess at frame rate for formants */ size = BUF_DURATION(sp) * freq; } else { freq = sp->freq; size = sp->file_size; } if((sf = new_signal(new_ext(sp->name,"fb.ed"),SIG_NEW, dup_header(sp->header), NULL,size,freq,dim))) { sf->file_size = sf->buff_size = size; if(freq != sp->freq) head_printf(sf->header,"frequency",&(sf->freq)); if(size != sp->file_size) head_printf(sf->header,"samples",&(sf->file_size)); if(!(dpp = (double**)malloc(sizeof(double*) * dim))) { printf("Problems allocating pointer array in create_dummy_sf()\n"); return NULL; } for(i=0; i<dim; i++) { if(!(dpp[i] = (double*)malloc(sizeof(double) * sf->file_size))) { printf("Problems allocating arrays for dummy formants\n"); return(NULL); } } if (sp->header && sp->header->magic == ESPS_MAGIC && sp->header->esps_hdr) { struct header *hdr; long fld_dim[1]; hdr = new_header(FT_FEA); sf->header->esps_hdr = hdr; set_pvd(hdr); sprintf(temp, "xwaves create_dummy_sf %s %s\n", sp->name, sf->name); add_comment(hdr, temp); *add_genhd_d("start_time", (double *) NULL, 1, hdr) = sp->start_time; *add_genhd_d("record_freq", (double *) NULL, 1, hdr) = freq; fld_dim[0] = dim/2; add_fea_fld("fm", (long)dim/2, 1, fld_dim, DOUBLE, (char **) NULL, hdr); add_fea_fld("bw", (long)dim/2, 1, fld_dim, DOUBLE, (char **) NULL, hdr); if (!(cpp = (caddr_t *) malloc(sizeof(caddr_t) * dim))) { printf("Can't allocate pointer array in create_dummy_sf()\n"); return NULL; } for (i = 0; i < dim; i++) cpp[i] = (caddr_t) dpp[i]; if (!(sf->types = (int *) malloc(sizeof(int) * dim))) { printf("Can't allocate types array in create_dummy_sf()\n"); return NULL; } for (i = 0; i < dim; i++) sf->types[i] = P_DOUBLES; sf->data = (caddr_t) cpp; sf->type = P_MIXED | SIG_FORMANTS | SIG_BINARY; } else { sf->data = (caddr_t)dpp; sf->type = P_DOUBLES | SIG_FORMANTS | SIG_ASCII; } dim /= 2; for(i=0; i<dim; i++) { /* create the dummy data */ k = i + dim; for(j=0, freq = 500 + i*1000, band = 60 + 0.05*freq; j < sf->file_size; j++) { dpp[i][j] = freq; dpp[k][j] = band; } } head_printf(sf->header,"type_code",&(sf->type)); head_printf(sf->header,"dimensions",&(sf->dim)); cp = temp; for(i=0; i< dim; i++) { sprintf(cp,"F%d ",i+1); cp = temp + strlen(temp); } for(i=0; i< dim; i++) { sprintf(cp,"B%d ",i+1); cp = temp + strlen(temp); } head_ident(sf->header,temp); if((sp->type & SPECIAL_SIGNALS) == SIG_LPC_POLES) head_printf(sf->header,"remark", "xwaves: created by hand-assignment of frequency candidates"); else head_printf(sf->header,"remark", "xwaves: created by hand-marking formant frequencies"); return(setup_formant_overlay(sf,vh,1)); } else printf("Can't create_dummy_sf()\n"); } else printf("Bad arguments to create_dummy_sf()\n"); return(NULL);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -