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

📄 sox.c

📁 linux下录音程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Sox - The Swiss Army Knife of Audio Manipulation. * * This is the main function for the command line sox program. * * July 5, 1991 * Copyright 1991 Lance Norskog And Sundry Contributors * This source code is freely redistributable and may be used for * any purpose.  This copyright notice must be maintained.  * Lance Norskog And Sundry Contributors are not responsible for  * the consequences of using this software. * * Change History: * * June 1, 1998 - Chris Bagwell (cbagwell@sprynet.com) *   Added patch to get volume working again.  Based on patch sent from *   Matija Nalis <mnalis@public.srce.hr>. *   Added command line switches to force format to ADPCM or GSM. * * September 12, 1998 - Chris Bagwell (cbagwell@sprynet.com) *   Reworked code that handled effects.  Wasn't correctly draining *   stereo effects and a few other problems. *   Made command usage (-h) show supported effects and file formats. *   (this is partially from a patch by Leigh Smith *    leigh@psychokiller.dialix.oz.au). * */ #include "st.h"#include "version.h"#include "patchlvl.h"#include <stdio.h>#include <string.h>#if	defined(unix) || defined(AMIGA) || defined(__OS2__)#include <sys/types.h>#include <sys/stat.h>#include <unistd.h>#include <fcntl.h>#include <stdlib.h>#ifdef HAS_GETOPT_H#include <getopt.h>#endif#endif#if	defined(__STDC__)#include <stdarg.h>#else#include <varargs.h>#endif#include <ctype.h>#ifdef VMS#include <errno.h>#include <perror.h>#define LASTCHAR        ']'#else#include <errno.h>#define LASTCHAR        '/'#endif/* * SOX main program. * * Rewrite for new nicer option syntax.  July 13, 1991. * Rewrite for separate effects library.  Sep. 15, 1991. * Incorporate Jimen Ching's fixes for real library operation: Aug 3, 1994. * Rewrite for multiple effects: Aug 24, 1994. */#ifdef AMIGA/* This is the Amiga version string */char amiversion[AmiVerSize]=AmiVerChars;      #endif /* AMIGA */#ifdef	DOSextern char writebuf[BUFSIZ];#endifint clipped = 0;		/* Volume change clipping errors */static LONG ibufl[BUFSIZ/2];	/* Left/right interleave buffers */static LONG ibufr[BUFSIZ/2];	static LONG obufl[BUFSIZ/2];static LONG obufr[BUFSIZ/2];void init();void doopts(P2(int, char **));void usage(P1(char *));int filetype(P1(int));void process();void statistics();LONG volumechange();void checkeffect(P1(eff_t));#ifdef NEED_GETOPTint getopt(P3(int,char **,char *));#endifint flow_effect(P1(int));int drain_effect(P1(int));struct soundstream informat, outformat;ft_t ft;#define MAXEFF 4struct effect eff;struct effect efftab[MAXEFF];	/* table of left/mono channel effects */struct effect efftabR[MAXEFF];	/* table of right channel effects */				/* efftab[0] is the input stream */int neffects;			/* # of effects */char *ifile, *ofile, *itype, *otype;IMPORT char *optarg;IMPORT int optind;int main(argc, argv)int argc;char **argv;{	myname = argv[0];	init();		ifile = ofile = NULL;	/* Get input format options */	ft = &informat;	doopts(argc, argv);	/* Get input file */	if (optind >= argc)		usage("No input file?");		ifile = argv[optind];	if (! strcmp(ifile, "-"))		ft->fp = stdin;	else if ((ft->fp = fopen(ifile, READBINARY)) == NULL)		fail("Can't open input file '%s': %s", 			ifile, strerror(errno));	ft->filename = ifile;	optind++;	/* If more arguments are left then look for -e to see if */	/* no output file is used, then just do an effect */	if (optind < argc && strcmp(argv[optind], "-e"))	    writing = 1;	else if (optind < argc) {	    writing = 0;	    optind++;  /* Move passed -e */	}	else	    writing = 1;  /* No arguments left but let next check fail */	    	/* Get output format options */	ft = &outformat;	doopts(argc, argv);	if (writing) {	    /* Get output file */	    if (optind >= argc)		usage("No output file?");	    ofile = argv[optind];	    ft->filename = ofile;	    /*	     * There are two choices here:	     *	1) stomp the old file - normal shell "> file" behavior	     *	2) fail if the old file already exists - csh mode	     */	    if (! strcmp(ofile, "-"))		ft->fp = stdout;	    else {#ifdef	unix		/*			 * Remove old file if it's a text file, but 		 * preserve Unix /dev/sound files.		 */		if ((ft->fp = fopen(ofile, WRITEBINARY)) && 		    (filetype(fileno(ft->fp)) == S_IFREG)) {		    fclose(ft->fp);		    unlink(ofile);		    creat(ofile, 0666);		    ft->fp = fopen(ofile, WRITEBINARY);		}#else		ft->fp = fopen(ofile, WRITEBINARY);#endif		if (ft->fp == NULL)		    fail("Can't open output file '%s': %s", 			 ofile, strerror(errno));#ifdef	DOS		if (setvbuf (ft->fp,writebuf,_IOFBF,sizeof(char)*BUFSIZ))		    fail("Can't set write buffer");#endif	    } /* end of else != stdout */	    	    /* Move passed filename */	    optind++;	} /* end if writing */	/* Get effect name */	if (optind < argc) {		eff.name = argv[optind];		optind++;		geteffect(&eff);		(* eff.h->getopts)(&eff, argc - optind, &argv[optind]);	} else {		eff.name = "null";		geteffect(&eff);	}	/* Check global arguments */	if (volume <= 0.0)		fail("Volume must be greater than 0.0");	#if	defined(unix) || defined(AMIGA)	informat.seekable  = (filetype(fileno(informat.fp)) == S_IFREG);	outformat.seekable = (filetype(fileno(outformat.fp)) == S_IFREG); #else#if	defined(DOS) || defined(__OS2__)	informat.seekable  = 1;	outformat.seekable = 1;#else	informat.seekable  = 0;	outformat.seekable = 0;#endif#endif	/* If file types have not been set with -t, set from file names. */	if (! informat.filetype) {		if ((informat.filetype = strrchr(ifile, LASTCHAR)) != NULL)			informat.filetype++;		else			informat.filetype = ifile;		if ((informat.filetype = strrchr(informat.filetype, '.')) != NULL)			informat.filetype++;		else /* Default to "auto" */			informat.filetype = "auto";	}	if (writing && ! outformat.filetype) {		if ((outformat.filetype = strrchr(ofile, LASTCHAR)) != NULL)			outformat.filetype++;		else			outformat.filetype = ofile;		if ((outformat.filetype = strrchr(outformat.filetype, '.')) != NULL)			outformat.filetype++;	}	/* Default the input comment to the filename. 	 * The output comment will be assigned when the informat 	 * structure is copied to the outformat. 	 */	informat.comment = informat.filename;	process();	statistics();	return(0);}#ifdef HAS_GETOPT_Hchar *getoptstr = "+r:v:t:c:phsuUAagbwlfdDxV";#elsechar *getoptstr = "r:v:t:c:phsuUAagbwlfdDxV";#endifvoid doopts(argc, argv)int argc;char **argv;{	int c;	char *str;	while ((c = getopt(argc, argv, getoptstr)) != -1) {		switch(c) {		case 'p':			soxpreview++;			break;		case 'h':			usage((char *)0);			/* no return from above */		case 't':			if (! ft) usage("-t");			ft->filetype = optarg;			if (ft->filetype[0] == '.')				ft->filetype++;			break;		case 'r':			if (! ft) usage("-r");			str = optarg;#ifdef __alpha__			if ((! sscanf(str, "%u", &ft->info.rate)) ||					(ft->info.rate <= 0))#else			if ((! sscanf(str, "%lu", &ft->info.rate)) ||					(ft->info.rate <= 0))#endif				fail("-r must be given a positive integer");			break;		case 'v':			if (! ft) usage("-v");			str = optarg;			if ((! sscanf(str, "%e", &volume)) ||					(volume <= 0))				fail("Volume value '%s' is not a number",					optarg);			dovolume = 1;			break;		case 'c':			if (! ft) usage("-c");			str = optarg;			if (! sscanf(str, "%d", &ft->info.channels))				fail("-c must be given a number");			break;		case 'b':			if (! ft) usage("-b");			ft->info.size = BYTE;			break;		case 'w':			if (! ft) usage("-w");			ft->info.size = WORD;			break;		case 'l':			if (! ft) usage("-l");			ft->info.size = DWORD;			break;		case 'f':			if (! ft) usage("-f");			ft->info.size = FLOAT;			break;		case 'd':			if (! ft) usage("-d");			ft->info.size = DOUBLE;			break;		case 'D':			if (! ft) usage("-D");			ft->info.size = IEEE;			break;		case 's':			if (! ft) usage("-s");			ft->info.style = SIGN2;			break;		case 'u':			if (! ft) usage("-u");			ft->info.style = UNSIGNED;			break;		case 'U':			if (! ft) usage("-U");			ft->info.style = ULAW;			break;		case 'A':			if (! ft) usage("-A");			ft->info.style = ALAW;			break;		case 'a':			if (! ft) usage("-a");			ft->info.style = ADPCM;			break;		case 'g':			if (! ft) usage("-g");			ft->info.style = GSM;			break;				case 'x':			if (! ft) usage("-x");			ft->swap = 1;			break;				case 'V':			verbose = 1;			break;		}	}}void init() {	/* init files */	informat.info.rate      = outformat.info.rate  = 0;	informat.info.size      = outformat.info.size  = -1;	informat.info.style     = outformat.info.style = -1;	informat.info.channels  = outformat.info.channels = -1;	informat.comment   = outformat.comment = NULL;	informat.swap      = 0;	informat.filetype  = outformat.filetype  = (char *) 0;	informat.fp        = stdin;	outformat.fp       = stdout;	informat.filename  = "input";	outformat.filename = "output";}/*  * Process input file -> effect table -> output file *	one buffer at a time */void process() {    LONG i;    int e, f, havedata;    gettype(&informat);    if (writing)	gettype(&outformat);        /* Read and write starters can change their formats. */    (* informat.h->startread)(&informat);    checkformat(&informat);        if (dovolume)	report("Volume factor: %f\n", volume);        report("Input file: using sample rate %lu\n\tsize %s, style %s, %d %s",	   informat.info.rate, sizes[informat.info.size], 	   styles[informat.info.style], informat.info.channels, 	   (informat.info.channels > 1) ? "channels" : "channel");    if (informat.comment)	report("Input file: comment \"%s\"\n", informat.comment);	    /* need to check EFF_REPORT */    if (writing) {	copyformat(&informat, &outformat);	(* outformat.h->startwrite)(&outformat);	checkformat(&outformat);	cmpformats(&informat, &outformat);	report("Output file: using sample rate %lu\n\tsize %s, style %s, %d %s",	       outformat.info.rate, sizes[outformat.info.size], 	       styles[outformat.info.style], outformat.info.channels, 	       (outformat.info.channels > 1) ? "channels" : "channel");	if (outformat.comment)	    report("Output file: comment \"%s\"\n", outformat.comment);    }    /* Very Important:      * Effect fabrication and start is called AFTER files open.     * Effect may write out data beforehand, and     * some formats don't know their sample rate until now.     */	    /* inform effect about signal information */    eff.ininfo = informat.info;    eff.outinfo = outformat.info;    for(i = 0; i < 8; i++) {	memcpy(&eff.loops[i], &informat.loops[i], sizeof(struct loopinfo));    }    eff.instr = informat.instr;    /* build efftab */    checkeffect(&eff);    /* Start all effects */    for(e = 1; e < neffects; e++) {	(* efftab[e].h->start)(&efftab[e]);	if (efftabR[e].name) 	    (* efftabR[e].h->start)(&efftabR[e]);    }    /* Reserve an output buffer for all effects */    for(e = 0; e < neffects; e++) {	efftab[e].obuf = (LONG *) malloc(BUFSIZ * sizeof(LONG));	if (efftabR[e].name) 	    efftabR[e].obuf = (LONG *) malloc(BUFSIZ * sizeof(LONG));    }    /* Read initial chunk of input data. */    efftab[0].olen = (*informat.h->read)(&informat, 					 efftab[0].obuf, (LONG) BUFSIZ);    efftab[0].odone = 0;    /* Change the volume of this initial input data if needed. */    if (dovolume)

⌨️ 快捷键说明

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