ftp.nice.ch/pub/next/unix/audio/cmix.s.tar.gz#/cmix/cmd/sndscale.c

This is sndscale.c in view mode; [Download] [Up]

# include <stdio.h>
# include <local/sfheader.h>
# include <sys/file.h>
# include <carl/carl.h>
# include <carl/libsf.h>
# include <sys/file.h>

/*	%W	%G%	IRCAM */

#define HIGHBIT 0100000

short aflg = 1, dflg;
char newname[1024];

main(argc,argv)
	char **argv;
{

	int fd,rnum,bufs = 1,fdone = 0;
	double rdur = 1.0 ,zdur = 2.0 ,atof();
	register double x;
	double inc = 0;
	long zerodur , rampdur ,totbytes ;
	SFHEADER hd;
	char *getsfname(), ch;

	unsigned short buf[8*1024]; 
	register unsigned short *sptr;
	short ask;
	int ofd;
	short firstin = 0,firstout = 0;

	setbuf(stdout,NULL);
	/* rdur is the ramp time and zdur is the duration of zeros */
	while ((ch = crack(argc, argv, "na|d|f|", TRUE)) != NULL) {
		switch (ch) {
			case 'a':
				zdur = sfexpr(arg_option, 1.0);
				if (zdur == 0)
					aflg = 0;
				aflg++;
				break;
			case 'd':
				rdur = sfexpr(arg_option, 1.0);
				dflg++;
				break;
			case 'z':
				aflg = 0; /* No added zeros */
				break;
			case 'f':
				strcpy(newname,getsfname(arg_option));
				break;
		}
	}


	if((fd = open(getsfname(argv[arg_index]),O_RDWR)) < 0) {
		perror(getsfname(argv[arg_index]));
		exit(1);
	}

	if(rheader(fd,&hd)) {
		printf("Bad header read\n");
		exit(1);
	}

	if(sfclass(&hd) != SF_SHORT) {
		printf("File not short integers\n");
		exit(1);
	}

	if(aflg)  {
		if(*newname == NULL)
			sprintf(newname,"%s.%s",getsfname(argv[arg_index]),"scale");
		if((ofd = open(newname,O_CREAT | O_RDWR | O_TRUNC,0644)) < 0) {
			printf("Can't creat new soundfile [%s]\n",newname);
			exit(1);
		}

		if(wheader(ofd,&hd)) {
			printf("Bad header read\n");
			exit(1);
		}
	}
	else
		ofd = fd;



	totbytes = 0;

	rampdur = rdur *  (double) (sfsrate(&hd) * sfclass(&hd) * sfchans(&hd));
	zerodur = (zdur + rdur) *  (double) (sfsrate(&hd) * sfclass(&hd) * sfchans(&hd));

	if(rampdur != 0)
		inc = 1./ (double) (rampdur / sfclass(&hd)); /* samples */

	if(aflg)
		bzero((char *) buf,sizeof(buf));
	else
		zerodur = rampdur;

	x = 0;

	if(rampdur)
		fprintf(stdout,"Fade in (%d bytes) ",rampdur);

	for(;;) {
		if(totbytes < rampdur) 
			if(rampdur - totbytes < 16 * 1024) 
					ask = rampdur - totbytes; 
			else 
				if(zerodur && zerodur - rampdur < 16* 1024)
					ask = zerodur - rampdur;
				else	
					ask = 16 * 1024;
		else 
			if(totbytes < zerodur) {
				if(firstin == 0) {
					fprintf(stdout," (zeros %d bytes) ",
						zerodur - rampdur);
					firstin++;
				}
				if(zerodur - totbytes < 16 * 1024) 
					ask = zerodur - totbytes; 
				else
					ask = 16 * 1024;
			}
		else
			ask = 16* 1024;

		if(!aflg || totbytes >=  zerodur) 
			rnum = read(fd,buf, ask);

		else { /* clear out buffer */
			rnum = ask;
			bzero((char *) buf, rnum);
		}

		if(rnum <= 0) 
			break;

		for(sptr = buf; sptr < &buf[rnum/sfclass(&hd)];sptr++) {
			*sptr += HIGHBIT;
			*sptr >>= 1;
		}

		if(totbytes < rampdur) { /* do ramp */
			register short *fred;

			for(fred = (short  *) buf; 
				fred < (short *) &buf[rnum/sizeof(short)]; fred++ ) {
				*fred = (short) ((double) *fred * x);
				x += inc;
			}
		}
		if(totbytes > zerodur)
			if(!fdone) {
				printf("\n");
				bufs = 1;
				fdone++;
			}
		if(fd == ofd)
			lseek(fd,-rnum,1);
		write(ofd,buf,rnum);
		fprintf(stdout,".%c",bufs % 10 ? ' ' : '\n');
		bufs++;
		totbytes += rnum;
	}

	if(rnum < 0) {
		printf("Bad read\n");
		exit(1);
	}
	/* At end of file */
	if(rampdur || zerodur) {
		if(aflg) {
			zerodur -= rampdur; /* amount of zeros to add */
			fprintf(stdout,"\n(zeros %d bytes) ",zerodur);
		}
		bufs = 1;
		x = 1;
		if(ofd == fd) 
			lseek(fd,-rampdur,2); /* Start fade out */
		else
			bzero((char *) buf,sizeof(buf));

		for(;;) {
			register short *fred;

			if(!aflg) 
				rnum = read(fd,buf,16*1024);
			else {

				if(zerodur > 0)
					rnum = zerodur < 16 * 1024 ? zerodur : 16 *1024;
				else
					rnum = rampdur < 16 * 1024 ? rampdur : 16 *1024;
				for(sptr = buf; sptr < &buf[rnum/sfclass(&hd)];sptr++) {
					*sptr = HIGHBIT; /* That is zero + */
					*sptr >>= 1;
				}
			}
			if(rnum <= 0)
				break;
	
			if(zerodur <= 0) {
				if(firstout == 0) {
					fprintf(stdout," Fade out (%d bytes)",
						rampdur);
					firstout++;
				}

				for(fred = (short  *) buf; 
					fred < (short *)&buf[rnum/sfclass(&hd)]; fred++ ) {
					*fred = (short) ((double) *fred * x);
					x -= inc;
				}
			}
			if(ofd == fd) 
				lseek(fd,-rnum,1); 
			else
				if(zerodur > 0)
					zerodur -= rnum;
				else
					rampdur -= rnum;

			write(ofd,buf,rnum);
			fprintf(stdout,".%c",bufs % 10 ? ' ' : '\n');
			bufs++;

		}
	}
	printf("\nDone\n");
	close(fd);
}

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.