⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sox.c

📁 linux下录音程序
💻 C
📖 第 1 页 / 共 2 页
字号:
	for (i = 0; i < efftab[0].olen; i++)	    efftab[0].obuf[i] = volumechange(efftab[0].obuf[i]);    /* Run input data through effects and get more until olen == 0 */    while (efftab[0].olen > 0) {	/* mark chain as empty */	for(e = 1; e < neffects; e++)	    efftab[e].odone = efftab[e].olen = 0;	do {	    /* run entire chain BACKWARDS: pull, don't push.*/	    /* this is because buffering system isn't a nice queueing system */	    for(e = neffects - 1; e > 0; e--) 		if (flow_effect(e))		    break;	    /* If outputing and output data was generated then write it */	    if (writing&&(efftab[neffects-1].olen>efftab[neffects-1].odone)) {		(* outformat.h->write)(&outformat, efftab[neffects-1].obuf, 				       (LONG) efftab[neffects-1].olen);	        efftab[neffects-1].odone = efftab[neffects-1].olen;	    }	    /* if stuff still in pipeline, set up to flow effects again */	    havedata = 0;	    for(e = 0; e < neffects - 1; e++)		if (efftab[e].odone < efftab[e].olen) {		    havedata = 1;		    break;		}	} while (havedata);	/* Read another chunk of input data. */	efftab[0].olen = (*informat.h->read)(&informat, 		efftab[0].obuf, (LONG) BUFSIZ);	efftab[0].odone = 0;	/* Change volume of these samples if needed. */	if (dovolume)	    for (i = 0; i < efftab[0].olen; i++)		efftab[0].obuf[i] = volumechange(efftab[0].obuf[i]);    }    /* Drain the effects out first to last,      * pushing residue through subsequent effects */    /* oh, what a tangled web we weave */    for(f = 1; f < neffects; f++)    {	while (1) {	    if (drain_effect(f) == 0)		break;		/* out of while (1) */		    if (writing&&efftab[neffects-1].olen > 0)		(* outformat.h->write)(&outformat, efftab[neffects-1].obuf,				       (LONG) efftab[neffects-1].olen);	    if (efftab[f].olen != BUFSIZ)		break;	}    }	    /* Very Important:      * Effect stop is called BEFORE files close.     * Effect may write out more data after.      */        for (e = 1; e < neffects; e++) {	(* efftab[e].h->stop)(&efftab[e]);	if (efftabR[e].name)	    (* efftabR[e].h->stop)(&efftabR[e]);    }    (* informat.h->stopread)(&informat);    fclose(informat.fp);    if (writing)        (* outformat.h->stopwrite)(&outformat);    if (writing)        fclose(outformat.fp);}int flow_effect(e)int e;{    LONG i, idone, odone, idonel, odonel, idoner, odoner;    LONG *ibuf, *obuf;    /* I have no input data ? */    if (efftab[e-1].odone == efftab[e-1].olen)	return 0;    if (! efftabR[e].name) {	/* No stereo data, or effect can handle stereo data so	 * run effect over entire buffer.	 */	idone = efftab[e-1].olen - efftab[e-1].odone;	odone = BUFSIZ;	(* efftab[e].h->flow)(&efftab[e], 			      &efftab[e-1].obuf[efftab[e-1].odone], 			      efftab[e].obuf, &idone, &odone);	efftab[e-1].odone += idone;	efftab[e].odone = 0;	efftab[e].olen = odone;    } else {		/* Put stereo data in two seperate buffers and run effect	 * on each of them.	 */	idone = efftab[e-1].olen - efftab[e-1].odone;	odone = BUFSIZ;	ibuf = &efftab[e-1].obuf[efftab[e-1].odone];	for(i = 0; i < idone; i += 2) {	    ibufl[i/2] = *ibuf++;	    ibufr[i/2] = *ibuf++;	}		/* left */	idonel = (idone + 1)/2;		/* odd-length logic */	odonel = odone/2;	(* efftab[e].h->flow)(&efftab[e], ibufl, obufl, &idonel, &odonel);		/* right */	idoner = idone/2;		/* odd-length logic */	odoner = odone/2;	(* efftabR[e].h->flow)(&efftabR[e], ibufr, obufr, &idoner, &odoner);	obuf = efftab[e].obuf;	 /* This loop implies left and right effect will always output	  * the same amount of data.	  */	for(i = 0; i < odoner; i++) {	    *obuf++ = obufl[i];	    *obuf++ = obufr[i];	}	efftab[e-1].odone += idonel + idoner;	efftab[e].odone = 0;	efftab[e].olen = odonel + odoner;    }     if (idone == 0) 	fail("Effect took no samples!");    return 1;}int drain_effect(e)int e;{    LONG i, olen, olenl, olenr;    LONG *obuf;    if (! efftabR[e].name) {	efftab[e].olen = BUFSIZ;	(* efftab[e].h->drain)(&efftab[e],efftab[e].obuf,			       &efftab[e].olen);    }    else {	olen = BUFSIZ;			/* left */	olenl = olen/2;	(* efftab[e].h->drain)(&efftab[e], obufl, &olenl);		/* right */	olenr = olen/2;	(* efftab[e].h->drain)(&efftabR[e], obufr, &olenr);		obuf = efftab[e].obuf;	/* This loop implies left and right effect will always output	 * the same amount of data.	 */	for(i = 0; i < olenr; i++) {	    *obuf++ = obufl[i];	    *obuf++ = obufr[i];	}	efftab[e].olen = olenl + olenr;    }    return(efftab[e].olen);}#define setin(eff, effname) \	{eff.name = effname; \	eff.ininfo.rate = informat.info.rate; \	eff.ininfo.channels = informat.info.channels; \	eff.outinfo.rate = informat.info.rate; \	eff.outinfo.channels = informat.info.channels;}#define setout(eff, effname) \	{eff.name = effname; \	eff.ininfo.rate = outformat.info.rate; \	eff.ininfo.channels = outformat.info.channels; \	eff.outinfo.rate = outformat.info.rate; \	eff.outinfo.channels = outformat.info.channels;}/* * If no effect given, decide what it should be. * Smart ruleset for multiple effects in sequence. * 	Puts user-specified effect in right place. */voidcheckeffect(effp)eff_t effp;{	int i, j;	int needchan = 0, needrate = 0;	/* if given effect does these, we don't need to add them */	needrate = (informat.info.rate != outformat.info.rate) &&		! (effp->h->flags & EFF_RATE);	needchan = (informat.info.channels != outformat.info.channels) &&		! (effp->h->flags & EFF_MCHAN);	neffects = 1;	/* effect #0 is the input stream */	/* inform all effects about all relevant changes */	for(i = 0; i < MAXEFF; i++) {		efftab[i].name = efftabR[i].name = (char *) 0;		/* inform effect about signal information */		efftab[i].ininfo = informat.info;		efftabR[i].ininfo = informat.info;		efftab[i].outinfo = outformat.info;		efftabR[i].outinfo = outformat.info;		for(j = 0; j < 8; j++) {			memcpy(&efftab[i].loops[j], 				&informat.loops[j], sizeof(struct loopinfo));			memcpy(&efftabR[i].loops[j], 				&informat.loops[j], sizeof(struct loopinfo));		}		efftab[i].instr = informat.instr;		efftabR[i].instr = informat.instr;	}	/* If not writing output, then just add the user specified effect.	 * This is to avoid channel and rate averaging since you don't have	 * a real output format.	 */	if (! writing) {		neffects = 2;		efftab[1].name = effp->name;		if ((informat.info.channels == 2) &&		   (! (effp->h->flags & EFF_MCHAN)))			efftabR[1].name = effp->name;	}	else if (soxpreview) {	    /* to go faster, i suppose rate could come first if downsampling */	    if (needchan && (informat.info.channels > outformat.info.channels))		{	        if (needrate) {		    neffects = 4;		    efftab[1].name = "avg";		    efftab[2].name = "rate";		    setout(efftab[3], effp->name);		} else {		    neffects = 3;		    efftab[1].name = "avg";		    setout(efftab[2], effp->name);		}	    } else if (needchan && 		    (informat.info.channels < outformat.info.channels)) {	        if (needrate) {		    neffects = 4;		    efftab[1].name = effp->name;		    efftab[1].outinfo.rate = informat.info.rate;		    efftab[1].outinfo.channels = informat.info.channels;		    efftab[2].name = "rate";		    efftab[3].name = "avg";		} else {		    neffects = 3;		    efftab[1].name = effp->name;		    efftab[1].outinfo.channels = informat.info.channels;		    efftab[2].name = "avg";		}	    } else {	        if (needrate) {		    neffects = 3;		    efftab[1].name = effp->name;		    efftab[1].outinfo.rate = informat.info.rate;		    efftab[2].name = "rate";		    if (informat.info.channels == 2)			    efftabR[2].name = "rate";		} else {		    neffects = 2;		    efftab[1].name = effp->name;		}		if ((informat.info.channels == 2) &&		    (! (effp->h->flags & EFF_MCHAN)))		        efftabR[1].name = effp->name;	    }	} else {	/* not preview mode */	    /* [ sum to mono,] [ then rate,] then effect */	    /* not the purest, but much faster */	    if (needchan && 			(informat.info.channels > outformat.info.channels)) {	        if (needrate && (informat.info.rate != outformat.info.rate)) {		    neffects = 4;		    efftab[1].name = "avg";		    efftab[2].name = effp->name;		    efftab[2].outinfo.rate = informat.info.rate;		    efftab[2].outinfo.channels = informat.info.channels;		    efftab[3].name = "rate";		} else {		    neffects = 3;		    efftab[1].name = "avg";		    efftab[2].name = effp->name;		    efftab[2].outinfo.rate = informat.info.rate;		    efftab[2].outinfo.channels = informat.info.channels;		}	    } else if (needchan && 			(informat.info.channels < outformat.info.channels)) {	        if (needrate) {		    neffects = 4;		    efftab[1].name = effp->name;		    if (! (effp->h->flags & EFF_MCHAN))			    efftabR[1].name = effp->name;		    efftab[1].outinfo.rate = informat.info.rate;		    efftab[1].outinfo.channels = informat.info.channels;		    efftab[2].name = "rate";		    efftab[3].name = "avg";		} else {		    neffects = 3;		    efftab[1].name = effp->name;		    if (! (effp->h->flags & EFF_MCHAN))			    efftabR[1].name = effp->name;		    efftab[1].outinfo.channels = informat.info.channels;		    efftab[2].name = "avg";		}	    } else {	        if (needrate) {		    neffects = 3;		    efftab[1].name = effp->name;		    efftab[1].outinfo.rate = informat.info.rate;		    efftab[2].name = "rate";		    if (informat.info.channels == 2)			    efftabR[2].name = "rate";		} else {		    neffects = 2;		    efftab[1].name = effp->name;		}		if ((informat.info.channels == 2) &&		    (! (effp->h->flags & EFF_MCHAN)))		        efftabR[1].name = effp->name;	    }	}	for(i = 1; i < neffects; i++) {		/* pointer comparison OK here */		/* shallow copy of initialized effect data */		/* XXX this assumes that effect_getopt() doesn't malloc() */		if (efftab[i].name == effp->name) {			memcpy(&efftab[i], &eff, sizeof(struct effect));			if (efftabR[i].name) 			    memcpy(&efftabR[i], &eff, sizeof(struct effect));		} else {			/* set up & give default opts for added effects */			geteffect(&efftab[i]);			(* efftab[i].h->getopts)(&efftab[i],0,(char *)0);			if (efftabR[i].name) 			    memcpy(&efftabR[i], &efftab[i], 				sizeof(struct effect));		}	}	    /* If a user doesn't specify an effect then a null entry could     * have been placed in the middle of the list above.  Remove     * those entries here.     */	for(i = 1; i < neffects; i++)	    if (! strcmp(efftab[i].name, "null")) {		for(; i < neffects; i++) {		    efftab[i] = efftab[i+1];		    efftabR[i] = efftabR[i+1];		}		neffects--;	    }}/* Guido Van Rossum fix */void statistics() {	if (dovolume && clipped > 0)		report("Volume change clipped %d samples", clipped);}LONG volumechange(y)LONG y;{	double y1;	y1 = y * volume;	if (y1 < -2147483647.0) {		y1 = -2147483647.0;		clipped++;	}	else if (y1 > 2147483647.0) {		y1 = 2147483647.0;		clipped++;	}	return y1;}#if	defined(unix) || defined(AMIGA)int filetype(fd)int fd;{	struct stat st;	fstat(fd, &st);	return st.st_mode & S_IFMT;}#endifchar *usagestr = "[ gopts ] [ fopts ] ifile [ fopts ] ofile [ effect [ effopts ] ]";void usage(opt)char *opt;{    int i;    #ifndef	DOS	/* single-threaded machines don't really need this */	fprintf(stderr, "%s: ", myname);#endif	if (verbose || !opt)		fprintf(stderr, "%s\n\n", version());	fprintf(stderr, "Usage: %s\n\n", usagestr);	if (opt)		fprintf(stderr, "Failed at: %s\n", opt);	else {	    fprintf(stderr,"gopts: -e -h -p -v volume -V\n\n");	    fprintf(stderr,"fopts: -r rate -c channels -s/-u/-U/-A/-a/-g -b/-w/-l/-f/-d/-D -x\n\n");	    fprintf(stderr, "effect: ");	    for (i = 1; effects[i].name != NULL; i++) {		fprintf(stderr, "%s ", effects[i].name);	    }	    fprintf(stderr, "\n\neffopts: depends on effect\n\n");	    fprintf(stderr, "Supported file formats: ");	    for (i = 0; formats[i].names != NULL; i++) {		/* only print the first name */		fprintf(stderr, "%s ", formats[i].names[0]);	    }	    fputc('\n', stderr);	}	exit(1);}/* called from util.c:fail */void cleanup() {	/* Close the input file and outputfile before exiting*/	if (informat.fp)		fclose(informat.fp);	if (outformat.fp) {		fclose(outformat.fp);		/* remove the output file because we failed, if it's ours. */		/* unless its a unix /dev/sound type file */#ifdef unix		if (filetype(fileno(outformat.fp)) == S_IFREG)#endif		    REMOVE(outformat.filename);	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -