This is nsfrestore.c in view mode; [Download] [Up]
#include "../H/sfheader.h" #include "nlabel.h" #include <stdio.h> #include <sys/file.h> #include <sys/types.h> #include <sys/mtio.h> #include <sys/ioctl.h> #include <sys/stat.h> #include <signal.h> #include <errno.h> #define BUFSIZE 65536 char tapename[16] = "/dev/rst1"; char *usefile; char buffer[BUFSIZE]; main(argc,argv) int argc; char *argv[]; { SFHEADER sfh1; struct stat sfst1; struct mtget mtget ; struct mtop mtop ; struct label label; char *cp,*sfout,*getsfcode(); /* char buffer[BUFSIZE]; */ int totalbytes,i,result,inbytes,sfile,tapeunit,tapefile,skipfile; int tapenumber; float duration; if(argc == 1) { usage: printf("Usage: -f [device] -l [tape number] -s [tape files to skip over] sf1 .. sfn\nDefaults: /dev/rsmt0, skip over label only\n"); exit(1); } usefile = tapename; skipfile = tapenumber = 0; tapefile = 1; system("date"); while((*++argv)[0] == '-') { argc -= 2; /* Take away two args */ for(cp = argv[0]+1; *cp; cp++) { switch(*cp) { /* Grap options */ case 'f': usefile = *++argv; break; case 's': tapefile = atoi(*++argv); skipfile = tapefile ? 1 : 0; /* skip this number of files before writing*/ break; case 'l': tapenumber = atoi(*++argv); break; default: printf("unknown option\n"); goto usage; } } } if(!tapenumber) { printf("You didn't specify a tape number with -n flag\n"); exit(-1); } if((tapeunit = open(usefile,0)) < 0) { printf("trouble opening tape unit\n"); exit(tapeunit); } if(read(tapeunit,&label,SIZEOFLABEL) != SIZEOFLABEL) { printf("Can't seem to read the label on this tape\n"); exit(tapeunit); } if(label.tapenumber != tapenumber) { printf ("this is tape number %d, you are asking for tape number %d\n" ,label.tapenumber,tapenumber); exit(tapeunit); } mtop.mt_op = MTFSF; mtop.mt_count = 1; if((ioctl(tapeunit,MTIOCTOP,&mtop)) == -1) { printf("error forward spacing tape past label eof\n"); exit(-2); } printf("Comment on tape %d: %s\n",label.tapenumber,label.comment); for(i=0; i<argc-1; i++) { sfout = argv[i]; if((sfile = open(sfout,O_CREAT | O_RDWR, 0644)) <= 0) { printf("Can't open file %s\n",sfout); exit(1); } totalbytes = 0; if(skipfile) { mtop.mt_op = MTFSF; mtop.mt_count = tapefile; if((ioctl(tapeunit,MTIOCTOP,&mtop)) == -1) { printf("error forward spacing tape\n"); exit(-2); } } skipfile = 0; /* read first record to get header printed up*/ if((inbytes = read(tapeunit,buffer,BUFSIZE)) != BUFSIZE) { printf("Bad read on tape unit %d %d\n",tapeunit,inbytes); exit(-1); } printf("-------------------------------------------------\n"); /* this allows any type of header off of tape */ if(parseHeader(buffer,&sfh1)) { printf("Bad sfheader on tape.\n"); exit(-1); } printsf(&sfh1); if((write(sfile,buffer,BUFSIZE)) != BUFSIZE) { printf("Bad write on soundfile\n"); exit(-1); } totalbytes = BUFSIZE; while(1) { if((inbytes=read(tapeunit,buffer,BUFSIZE)) <= 0) { printf("reached eof on input\n"); close(sfile); break; } if(write(sfile,buffer,inbytes) != inbytes) { printf("Bad write on sound file\n"); close(sfile); close(tapeunit); exit(0); } totalbytes += inbytes; } duration = (float)totalbytes/(float)sfclass(&sfh1)/ (float)sfchans(&sfh1)/sfsrate(&sfh1); tapefile++; printf ("Bytes restored = %d, duration = %f, tapefile = %d\n\n\n", totalbytes,duration,tapefile); fflush(stdout); close(sfile); } close(tapeunit); } static SFCODE ampcode = { SF_MAXAMP, sizeof(SFMAXAMP) + sizeof(SFCODE) }; int parseHeader(buff,header) SFHEADER *header; char *buff; { int i; SFMAXAMP sfmnew; char *pointer; /* read in 1kb first, to see if hybrid header is present */ bcopy(buff,(char *) header,SIZEOF_BSD_HEADER); /* if file has IRCAM-style header */ if((header)->sfinfo.NeXTheader.magic == SF_MAGIC) return(parseIrcamHeader(header)); /* if magic number is neither IRCAM nor local, we cant read it */ /* in case it is byte-swapped, give a message saying so */ if((header)->sfinfo.NeXTheader.magic == 1688404224) { fprintf(stderr, "This file must be byte-swapped before using!\n"); return 1; } if((header)->sfinfo.NeXTheader.magic != SND_MAGIC) return 1; /* if hybrid header is there, we are done here */ if((header)->sfinfo.sf_magic == SF_MAGIC) { fprintf(stderr, "This is a hybrid IRCAM/NeXT soundfile.\n"); return 0; } /* else, if file being read is native NeXT soundfile... */ fprintf(stderr, "This is a native NeXT soundfile.\n"); /* zero out new header after NeXT portion */ pointer = (char *)header; for(i=29; i<SIZEOF_BSD_HEADER; i++) *(pointer+i) = 0; /* load all values from native header into hybrid header */ (header)->sfinfo.sf_magic = 0; /* so we know it is native NeXT file */ (header)->sfinfo.sf_srate = (header)->sfinfo.NeXTheader.samplingRate; (header)->sfinfo.sf_chans = (header)->sfinfo.NeXTheader.channelCount; switch(header->sfinfo.NeXTheader.dataFormat) { case SND_FORMAT_FLOAT: (header)->sfinfo.sf_packmode = SF_FLOAT; break; case SND_FORMAT_LINEAR_16: (header)->sfinfo.sf_packmode = SF_SHORT; break; default: fprintf(stderr, "only float and short files can be used.\n"); return 1; } for(i=0; i<2; i++) { sfmaxamp(&sfmnew,i)=0; sfmaxamploc(&sfmnew,i)=0; } sfmaxamptime(&sfmnew) = 0; putsfcode(header,&sfmnew,&code); return 0; } int parseIrcamHeader(hd) SFHEADER *hd; { char *ptr = (char *) hd; int i; SFMAXAMP sfmnew; fprintf(stderr, "This is an IRCAM style soundfile.\n"); /* copy everything in header (minus a small chunk) to the location in the header it needs to be in a hybrid header. We loose 28 chars from the end of the comment, but who uses that much comment? */ bcopy(ptr, ptr + SIZEOF_NeXT_HEADER, sizeof(SFHEADER) - SIZEOF_NeXT_HEADER); /* and then zero out beginning and set the new magic number */ bzero(ptr, SIZEOF_NeXT_HEADER); /* if no amp code in header, put one */ if(getsfcode(hd, SF_MAXAMP) == NULL) { for(i=0; i<2; i++) { sfmaxamp(&sfmnew,i)=0; sfmaxamploc(&sfmnew,i)=0; } sfmaxamptime(&sfmnew) = 0; if(putsfcode(hd,&sfmnew,&code) < 0) { fprintf(stderr, "Unable to add new amp sfcode.\n"); return 1; } } /* set the magic number at the beginning to be the IRCAM magic number, to signal that this should be written back out as such. */ hd->sfinfo.NeXTheader.magic = SF_MAGIC; return 0; }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.