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.