This is lpcplot.c in view mode; [Download] [Up]
/* program to display and edit lpc analysis file. It has 4 commands. 1) n frame1 frame2 will display frame1 to frame2. If frame2 is 0 it will begin current chunk size on frame1. If frame1 is negative it will backup that many frames and display current chunk size from there. If neither frame1 or frame2 is specified it will simply display previous segment again. 2) p frame1 frame2 mult botcps topcps Multiply the pitches of frames frame1 to frame2 by mult if the current pitch is >= botcps and <=topcps. default for botcps and top cps are 0 and 999999. If mult is 0 it will interpolate pitches in these frames according to the frequencies of frame frame1-1 and frame2+1. If frame2 is 0 it defaults to frame1. Thus p 100 will simply replace the frequency of frame100 by interpolating between frames 99 and 101. 3) v frame1 frame2 value. This will add value to the error numbers of frames frame1 toframe2. In this way you can force a voiced or unvoiced decision by subtracting 1 or adding 1, respectively. 4) a frame1 frame2 value This will multiply rms by value for frames frame1 to frame2. In this way you can force some amplitudes to be louder than others. 5) null line (blank space-return) this will simply display the next chunk of frames according to the currently defined chunk size. */ #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #define FLOAT 4 #define THRESH 2 #define AMP 1 #define RESIDAMP 0 #define PITCH 3 /* location 0 is residual rms, these are other values */ #define NUMBERS 32 /* numbers take up about 32 columns */ #define POFFSET (long)(PITCH*FLOAT) /* byte offset for pitch value in frame*/ #define VOFFSET (long)(THRESH*FLOAT) /* byte offset for voiced/unvoiced test*/ #define AOFFSET (long)(RESIDAMP*FLOAT) /* byte offset for resid amp*/ int anal; char buffer[2048]; char *bufp; float c[50]; int endframe = 0; /* used by getfr, reset to 0 to force reread of disk */ int NPOLES; int FRAMSIZE; int FPREC = 1; int RECSIZE; int BPREC; int BPFRAME; main(argc,argv) int argc; char *argv[]; { struct stat st; int j,i,xframe1,xframe2,frame1,frame2,apoints,ppoints; int range,diff; float pbot,ptop,pmult,vval; int width; int shutup(),(*oldint)(); float thresh,amax,amin,pmax,pmin; char *output; if(argc == 1) { printf("usage:\n lpcplot lpc_data_set\n commands:\n"); usage(); exit(); } printf(" \n"); // seem to have to invoke printf first ???? output = argv[1]; if((anal = open(output,2)) < 0) { fprintf(stderr," Can't open anal file\n"); exit(1); } fprintf(stderr," Enter npoles, thresh\t"); scanf("%d %f",&NPOLES,&thresh); width = 80; /* hardwire 80 column output */ range = (width - NUMBERS)/2; fstat(anal,&st); printf("Last frame is %d. Type ? for list of commands\n",st.st_size/((NPOLES+4)*4)-1); FRAMSIZE = (NPOLES+4); RECSIZE = (FPREC*FRAMSIZE); BPREC = (RECSIZE*FLOAT); BPFRAME = (FRAMSIZE*FLOAT); while(1) { while(1) { next: gets(buffer); bufp = buffer; if(*bufp == 'n') { xframe1=frame1; xframe2=frame2; frame2 = 0; sscanf(++bufp,"%d %d",&frame1,&frame2); if(frame1 < 0) {/*back up but keep same range*/ frame1 += xframe2; frame2 = (xframe2 - xframe1)+frame1; } if(!frame2) frame2 = (xframe2-xframe1)+frame1; break; } if(*bufp == ' ') { diff=frame2-frame1; frame1=frame2+1; frame2=frame1+diff; break; } if(*bufp == 'p') { /* correct pitch values */ xframe1=xframe2=pbot=pmult=0; ptop = 999999.; sscanf(++bufp,"%d %d %f %f %f", &xframe1,&xframe2,&pmult,&pbot,&ptop); if(!xframe2) xframe2=xframe1; pchalter(xframe1,xframe2,pbot,ptop,pmult); endframe = 0; goto next; } if(*bufp == '?') { usage(); goto next; } if(*bufp == 'v') { /* correct thresh values * add 1 to force uv or subt 1 * to force voiced */ sscanf(++bufp,"%d %d %f", &xframe1,&xframe2,&vval); if(!xframe2) xframe2=xframe1; if(!vval) { fprintf(stderr, "you didnt specify a 3rd arg\n"); goto next; } valter(xframe1,xframe2,vval); endframe=0; goto next; } if(*bufp == 'a') { /* correct amp values */ sscanf(++bufp,"%d %d %f", &xframe1,&xframe2,&vval); if(!xframe2) xframe2=xframe1; if(!vval) { fprintf(stderr, "you didnt specify a 3rd arg\n"); goto next; } aalter(xframe1,xframe2,vval); endframe=0; goto next; } fprintf(stderr,"----> ?\t"); } pmax=amax=0; pmin=amin=99999999.; for(i=frame1;i<=frame2;i++) { if(getfr(i,c) == -1) break; if(c[AMP] > amax) amax = c[AMP]; if(c[AMP] < amin) amin = c[AMP]; if(c[PITCH] > pmax) pmax = c[PITCH]; if(c[PITCH] < pmin) pmin = c[PITCH]; } ppoints = apoints = range; for(i=frame1;i<=frame2;i++) { if(getfr(i,c) == -1) break; if(pmax != pmin) ppoints = ((c[PITCH]-pmin)/(pmax-pmin)) * range; if(amax != amin) apoints = ((c[AMP]-amin)/(amax-amin)) * range; printf("%5d ",i); printf("v%0.4f p%8.3f ",c[THRESH],c[PITCH]); for(j=0;j<ppoints;j++) { if(c[THRESH] < thresh) putchar('*'); else putchar('-'); } for(j=ppoints;j<range;j++) putchar(' '); printf("a%5.0f",c[AMP]); for(j=0;j<apoints;j++) { if(c[THRESH] < thresh) putchar('*'); else putchar('-'); } printf("\n"); } } } pchalter(frame1,frame2,pbot,ptop,pmult) float pbot,ptop,pmult; { int i,n; float begin,end,nframes; if(!pmult) { if(getfr((frame1-1),c) == -1) return; begin = c[PITCH]; if(getfr((frame2+1),c) == -1) return; end = c[PITCH]; nframes = 2. + frame2-frame1; } for(i=frame1;i<=frame2;i++) { if(getfr(i,c) == -1) break; if(!pmult) { c[PITCH] = begin + ((float)(i-frame1+1)/nframes) * (end-begin); if((lseek(anal,((long)i*(long)BPFRAME+POFFSET),0)) < 0) { fprintf(stderr,"bad lseek\n"); exit(-1); } if((n=write(anal,(char *)(c+PITCH),FLOAT)) !=FLOAT) { fprintf(stderr,"bad write %d\n",n); exit(-1); } } else if(c[PITCH] >= pbot && c[PITCH] <= ptop) { if((lseek(anal,((long)i*(long)BPFRAME+POFFSET),0)) < 0) { fprintf(stderr,"bad lseek\n"); exit(-1); } c[PITCH] *= pmult; if((n=write(anal,(char *)(c+PITCH),FLOAT)) !=FLOAT) { fprintf(stderr,"bad write %d\n",n); exit(-1); } } } } aalter(frame1,frame2,vval) float vval; { int i,n; for(i=frame1; i<=frame2; i++) { if(getfr(i,c) == -1) break; c[RESIDAMP] *= vval; c[AMP] *= vval; if((lseek(anal,((long)i*(long)BPFRAME+AOFFSET),0)) < 0) { fprintf(stderr,"bad lseek\n"); exit(-1); } if((n=write(anal,(char *)(c+RESIDAMP),2 * FLOAT)) != (2 * FLOAT)) { fprintf(stderr,"bad write %d\n",n); exit(-1); } } } valter(frame1,frame2,vval) float vval; { int i,n; for(i=frame1; i<=frame2; i++) { if(getfr(i,c) == -1) break; c[THRESH] += vval; if((lseek(anal,((long)i*(long)BPFRAME+VOFFSET),0)) < 0) { fprintf(stderr,"bad lseek\n"); exit(-1); } if((n=write(anal,(char *)(c+THRESH),FLOAT)) !=FLOAT) { fprintf(stderr,"bad write %d\n",n); exit(-1); } } } getfr(frame,c) float *c; { int i,j,nfr,nread; static float array[1000]; static int oldframe = 0; if(!((frame >= oldframe) && (frame < endframe))) { if(lseek(anal,((long)frame*(long)BPFRAME),0) < 0) { fprintf(stderr,"bad lseek on anal read\n"); return(-1); } if((nread = read(anal,(char *)array,BPREC)) <= 0) { fprintf(stderr,"bad read on anal file\n"); return(-1); } if(nread < BPREC) { nfr = nread/BPFRAME; for(i=nfr*FRAMSIZE; i<RECSIZE; i++) array[i]=0; } oldframe = frame; endframe = oldframe + FPREC - 1; } for(i=(frame-oldframe)*FRAMSIZE,j=0; j<FRAMSIZE; i++,j++) *(c+j) = *(array+i); return(0); } usage() { printf(" lpcplot commands: 1) n frame1 frame2 will display frame1 to frame2. If frame2 is 0 it will begin current chunk size on frame1. If frame1 is negative it will backup that many frames and display current chunk size from there. If neither frame1 or frame2 is specified it will simply display previous segment again. 2) p frame1 frame2 mult botcps topcps Multiply the pitches of frames frame1 to frame2 by mult if the current pitch is >= botcps and <=topcps. default for botcps and top cps are 0 and 999999. If mult is 0 it will interpolate pitches in these frames according to the frequencies of frame frame1-1 and frame2+1. If frame2 is 0 it defaults to frame1. Thus p 100 will simply replace the frequency of frame100 by interpolating between frames 99 and 101. 3) v frame1 frame2 value. This will add value to the error numbers of frames frame1 toframe2. In this way you can force a voiced or unvoiced decision by subtracting 1 or adding 1, respectively. 4) null line (blank space-return) this will simply display the next chunk of frames according to the currently defined chunk size.\n"); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.