This is rescale.c in view mode; [Download] [Up]
/* fast program to rescale from floating point file to integer file. It will create an integer file called filename.short if you don't specify an output file. */ /* could also make this into a neat general purpose alteration program ?*/ /* TODO create option to skip on input and output, and specify duration and optional peak */ #include "../H/sfheader.h" #include "rescale.h" #include <stdio.h> #include <sys/file.h> #include <sys/types.h> #include <sys/stat.h> #include <signal.h> #include <errno.h> #define BUFSIZE 32768 static SFCODE ampcode = { SF_MAXAMP, sizeof(SFMAXAMP) + sizeof(SFCODE) }; static SFCODE commentcode = { SF_COMMENT, MINCOMM + sizeof(SFCODE) }; main(argc,argv) int argc; char *argv[]; { SFMAXAMP sfm,sfmnew; SFCOMMENT sfcm; SFHEADER sfh1,sfh2; SFCODE *sizer; struct stat sfst1,sfst2; char *cp,*sfin,*sfout,*getsfcode(); double atof(); short outbuffer[BUFSIZE]; float inbuffer[BUFSIZE]; int i,n,bytes,words,inbytes,outbytes,sf1,sf2,result,readbytes,durbytes; int replace,empty,skipbytes,outskipbytes,newfile; float opeak,factor,skpin,dur,newpeak,outskip; char command[256]; char newname[128]; char *point,*point2,*strcat(); short *bufp; float Oresult = 32767; if(argc == 1) { usage: printf("usage: -s inskip -d dur -o outskip -p peakamp -P desired peak -r [write over floating-point file] -e emptybuffers_at_end -z [create new file] -f factor inputfile [outputfile]\n"); printf("defaults: s=0, d=to_eof, o=0, p=input_peak, e=1, P=32767, f=P/input_peak write over old file, outputfile=inputfile.short\n"); exit(0); } replace=newfile=skpin=dur=newpeak=outskip=factor=0; empty = 1; /* defaults to 1 empty buffers at end*/ while((*++argv)[0] == '-') { argc -= 2; /* Take away two args */ for(cp = argv[0]+1; *cp; cp++) { switch(*cp) { /* Grap options */ case 'r': replace = 1; printf("Writing over floating-point file\n"); break; case 's': skpin = atof(*++argv); printf("input skip = %f\n",skpin); break; case 'd': dur = atof(*++argv); printf("rescale duration = %f\n",dur); empty = 0; /* no empty buffers for splice */ break; case 'f': factor = atof(*++argv); printf("specified factor = %f\n",factor); break; case 'p': newpeak = atof(*++argv); printf("specified peak = %f\n",newpeak); break; case 'P': Oresult = atof(*++argv); printf("resultant peak = %f\n",Oresult); break; case 'o': outskip = atof(*++argv); printf("output skip = %f\n",outskip); break; case 'e': empty = atof(*++argv); printf("write %d empty buffers at end\n",empty); break; case 'z': newfile = 1; break; default: printf("uh-oh, unkown option\n"); goto usage; } } } sfin = argv[0]; sfout = argv[1]; readopensf(sfin,sf1,sfh1,sfst1,"rescale",result); if(result < 0) { close(sf1); exit(1); } /* do input skip on input file*/ if(skipbytes = skpin * sfclass(&sfh1) * sfsrate(&sfh1) * sfchans(&sfh1)) { skipbytes -= skipbytes % (sfclass(&sfh1) * sfchans(&sfh1)); /* make sure it lands on sample block */ if(sflseek(sf1,skipbytes,0) == -1) { printf("Bad skip on input file\n"); exit(1); } } printsf(&sfh1); if(sfclass(&sfh1) == SF_SHORT) { printf("Note: Input file has short integers.\n"); } cp = getsfcode(&sfh1,SF_MAXAMP); bcopy(cp + sizeof(SFCODE), (char *) &sfm, sizeof(SFMAXAMP)); for(i=0,opeak=0; i<sfchans(&sfh1); i++) if(sfmaxamp(&sfm,i) > opeak) opeak = sfmaxamp(&sfm,i); opeak = newpeak ? newpeak : opeak; if(!opeak) { printf("Sorry, but I have no peak amplitude for this file.\nPut one in with sfhedit, sndpeak, or use the -p flag in rescale.\n"); close(sf1); exit(-3); } printf("Peak amplitude of input file is %e\n",opeak); if(!factor) factor = Oresult/opeak; printf("factor = %f\n",factor); if((cp=getsfcode(&sfh1,SF_COMMENT))) { sizer = (SFCODE *) cp; bcopy(cp + sizeof(SFCODE) , (char *) &sfcm, sizer->bsize); } if(replace) sfout=sfin; newrwopensf(sfout,sf2,sfh2,sfst2,"rescale",result,2); if(result < 0) { if(sfout == NULL) { point = sfin; if(sfclass(&sfh1) == SF_FLOAT) point = strcat(sfin,".short"); else point = strcat(sfin,".xshort"); } else point = sfout; sfmagic(&sfh2) = SF_MAGIC; sfclass(&sfh2) = SF_SHORT; sfchans(&sfh2) = sfchans(&sfh1); sfsrate(&sfh2) = sfsrate(&sfh1); if((sf2 = open(point,O_CREAT|O_RDWR,0644)) < 0 ) { printf("Can't open file %s\n",point); exit(-2); } if(newfile) ftruncate(sf2,SIZEOF_HEADER); for(i=0; i<sfchans(&sfh2); i++) { sfmaxamp(&sfmnew,i)=sfmaxamp(&sfm,i)*factor; sfmaxamploc(&sfmnew,i)=sfmaxamploc(&sfm,i); } sfmaxamptime(&sfmnew) = sfmaxamptime(&sfm); putsfcode(&sfh2,&sfmnew,&code); if (putsfcode(&sfh2,&sfcm,&commentcode) < 0) { printf("comment didn't get written, sorry!\n"); exit(-1); } printf ("\nCreating output file: %s\n",point); if(wheader(sf2,(char *)&sfh2)) { printf("Can't seem to write header on file %s\n" ,point); perror("main"); exit(-1); } } else if(!replace) printsf(&sfh2); if(!replace && (sfclass(&sfh2) != SF_SHORT)) { printf("Output file must have short integers.\n"); exit(-1); } /* do output skip*/ if(outskipbytes = outskip * sfclass(&sfh2) * sfsrate(&sfh2) * sfchans(&sfh2)) { outskipbytes -= outskipbytes % (sfclass(&sfh2) * sfchans(&sfh2)); /* make sure it lands on sample block */ if(sflseek(sf2,outskipbytes,0) == -1) { printf("Bad skip on output file\n"); exit(1); } } readbytes = inbytes = BUFSIZE * sfclass(&sfh1); durbytes = dur * sfclass(&sfh1) * sfchans(&sfh1) * sfsrate(&sfh1); fflush (stdout); fprintf(stderr,"Rescaling....\t"); bufp = (short *)inbuffer; while(1) { if(dur) { inbytes = (durbytes > readbytes) ? inbytes : durbytes; durbytes -= inbytes; } if((bytes = read(sf1,(char *)inbuffer,inbytes)) <= 0) { printf("reached eof on input\n"); close(sf1); break; } words = bytes/sfclass(&sfh1); outbytes = words * SF_SHORT; if(sfclass(&sfh1) == SF_SHORT) for(i=0; i<words; i++) outbuffer[i] = (short)((float)bufp[i] * factor); else for(i=0; i<words; i++) outbuffer[i] = (short) (inbuffer[i] * factor); if(write(sf2,(char *)outbuffer,outbytes) != outbytes) { printf("Bad write on output file\n"); close(sf1); close(sf2); exit(0); } } /* write empty buffers */ for(i=0; i<words; i++) outbuffer[i] = 0; for(i=0; i<empty; i++) if(n=write(sf2,(char *)outbuffer,outbytes) != outbytes) { printf("Bad write on output file\n"); close(sf2); exit(0); } if(replace) { i = lseek(sf2,0,1); if(ftruncate(sf2,i) < 0) printf("Bad truncation\n"); lseek(sf2,0,0); for(i=0; i<sfchans(&sfh2); i++) { sfmaxamp(&sfmnew,i)=sfmaxamp(&sfm,i)*factor; sfmaxamploc(&sfmnew,i)=sfmaxamploc(&sfm,i); } sfmaxamptime(&sfmnew) = sfmaxamptime(&sfm); putsfcode(&sfh2,&sfmnew,&code); sfclass(&sfh2) = SF_SHORT; if(wheader(sf2,(char *)&sfh2)) { printf("Can't seem to write header on file %s\n" ,point); perror("main"); exit(-1); } if(fsync(sf2) < 0) printf("bad fsync\n"); } putlength(point,sf2,&sfh2); printf("%s\n",point); close(sf1); close(sf2); printf("\ndone.\n"); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.