This is getmaxamp.c in view mode; [Download] [Up]
# include <stdio.h> #ifndef LINT static char SccsId[] = "%W% %G% IRCAM"; #endif # include <sys/types.h> # include <sys/stat.h> # include <sys/file.h> # include "../H/sfheader.h" # define BAD goto bad /* This saves half the CPU time for the job just in the use of the soubroutine call as abs() and fabs() are assembler routines! */ # define abs(x) ((x) < 0 ? -(x) : (x)) /* This routine will find the peak absolute value per channel and the sample location of an existing soundfile window and if the entire file was scanned and update is turned on and the user has permission that information plus a timetag will be put in the header */ static float maxamp[SF_MAXCHAN]; static long bytes,totalbytes, maxloc[SF_MAXCHAN]; static SFMAXAMP sfm; static SFCODE ampcode = { SF_MAXAMP, sizeof(SFMAXAMP) + sizeof(SFCODE) }; SFMAXAMP *getmaxamp(fd,update,startsampf,dursampf) long startsampf, dursampf; { int readbyte; int i; SFHEADER hd; char *buffer,*malloc(),*getsfname(); struct stat st; long oldloc,samples; /* Get memory for buffers */ buffer = malloc(SF_BUFSIZE); if(!buffer) return(NULL);; if(fstat(fd,&st) == -1) return(NULL); oldloc = lseek(fd,0,1); lseek(fd,0,0); /* To reread header */ if(rheader(fd,&hd)) BAD; totalbytes = bytes = dursampf * sfchans(&hd) * sfclass(&hd); startsampf = startsampf * sfchans(&hd) * sfclass(&hd); if (sfbsize(&st) < startsampf + totalbytes) return(NULL); bzero(&sfm,sizeof(sfm)); bzero(maxamp,sizeof(maxamp)); bzero(maxloc,sizeof(maxloc)); sflseek(fd,startsampf,0); while(bytes > 0) { /* For all of the samples */ if((readbyte = read(fd,buffer,SF_BUFSIZE)) < 0) BAD; samples = readbyte/sfclass(&hd); if(sfclass(&hd) == SF_FLOAT) ffindamp(buffer,samples,sfchans(&hd)); else sfindamp(buffer,samples,sfchans(&hd)); bytes -= readbyte; } for(i = 0; i < sfchans(&hd); i++) { sfmaxamploc(&sfm,i) = maxloc[i]/sfclass(&hd); sfmaxamp(&sfm,i) = maxamp[i]; } if(update && (startsampf + totalbytes == sfbsize(&st))) { /* Update the header */ sfmaxamptime(&sfm) = time(0); if(putsfcode(&hd,&sfm,&code)) return(NULL); lseek(fd,0,0); if(wheader(fd,&hd)) BAD; } lseek(fd,oldloc,0); return(&sfm); bad: lseek(fd,oldloc,0); return(NULL); } ffindamp(buf,samples,chans) char *buf; long samples; { register float *fbuffer = (float *) buf; register float val; register int i; while(samples > 0) { for(i = 0; i < chans; i++) { val = abs(*fbuffer); if(val > maxamp[i]) { maxamp[i] = val; maxloc[i] = totalbytes - bytes + (char *) fbuffer - buf; } fbuffer++; } samples -= chans; } } sfindamp(buf,samples,chans) char *buf; register long samples; { register short *sbuffer = (short *) buf; register float val; register int i; while(samples > 0) { for(i = 0; i < chans; i++) { val = abs(*sbuffer); if(val > maxamp[i]) { maxamp[i] = val; maxloc[i] = totalbytes - bytes + (char *) sbuffer - buf; } sbuffer++; } samples -= chans; } }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.