shithub: sox

Download patch

ref: f58321658de6c9a7c69a130b0c99eb1c350b49d2
parent: 01dddda9b91c640637d95d3ac0d0c01abc437648
author: cbagwell <cbagwell>
date: Sun Aug 26 19:20:48 EDT 2001

Removing mix.c file.

--- a/Changelog
+++ b/Changelog
@@ -66,6 +66,9 @@
   o Heikki Leinonen submitted a silence effect that will trim off
     silence from the beginning of a file.  cbagwell made some modifications
     to trim off front and back as well as some other tweaks.
+  o Made the "auto" effect the default file handler for input files.
+    Also have auto handler now use file extensions if it can't figure
+    it out.
 
 sox-12.17.1
 -----------
--- a/mix.c
+++ /dev/null
@@ -1,617 +1,0 @@
-/*
- * Mix - the audiofile mixing program of SOX
- *
- * This is the main function for the command line sox program.
- *
- * January 26, 2001
- * Copyright 2001 ben last, Lance Norskog And Sundry Contributors
- * This source code is freely redistributable and may be used for
- * any purpose.  This copyright notice must be maintained. 
- * ben last, Lance Norskog And Sundry Contributors are not responsible
- * for the consequences of using this software.
- *
- * Change History:
- *
- * January 26, 2001 - ben last (ben@benlast.com)
- *   Derived mix.c from sox.c and then rewrote it for
- *   mix functionality.
- */ 
-
-#include "st.h"
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>		/* for malloc() */
-#ifdef HAVE_MALLOC_H
-#include <malloc.h>
-#endif
-#include <errno.h>
-#include <sys/types.h>		/* for fstat() */
-#include <sys/stat.h>		/* for fstat() */
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>		/* for unlink() */
-#endif
-
-#ifdef HAVE_GETOPT_H
-#include <getopt.h>
-#else
-#ifndef HAVE_GETOPT
-int getopt(int,char **,char *);
-extern char *optarg;
-extern int optind;
-#endif
-#endif
-
-#ifdef VMS
-#include <perror.h>
-#define LASTCHAR        ']'
-#else
-#define LASTCHAR        '/'
-#endif
-
-/*
- * SOX mix main program.
- */
-
-static int dovolume = 0;	/* User wants volume change */
-static double volume = 1.0;	/* Linear volume change */
-static int clipped = 0;		/* Volume change clipping errors */
-static int writing = 0;		/* are we writing to a file? */
-
-static void init();
-static void doopts(int, char **);
-static void usage(char *);
-static int filetype(int);
-static void process();
-static void statistics();
-static LONG volumechange();
-
-struct st_soundstream informat, mixformat, outformat;
-
-static ft_t ft;
-
-char *ifile, *mfile, *ofile, *itype, *mtype, *otype;
-extern char *optarg;
-extern int optind;
-
-int main(argc, argv)
-int argc;
-char **argv;
-{
-	myname = argv[0];
-
-	init();
-	
-	ifile = mfile = 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)
-		st_fail("Can't open input file '%s': %s", 
-			ifile, strerror(errno));
-	ft->filename = ifile;
-#if	defined(DUMB_FILESYSTEM)
-	ft->seekable = 0;
-#else
-	ft->seekable = (filetype(fileno(informat.fp)) == S_IFREG);
-#endif
-
-	optind++;
-
-	/* Get mix format options */
-	ft = &mixformat;
-	doopts(argc, argv);
-	/* Get mix file */
-	if (optind >= argc)
-		usage("No mix file?");
-	
-	mfile = argv[optind];
-	if (! strcmp(mfile, "-"))
-		ft->fp = stdin;
-	else if ((ft->fp = fopen(mfile, READBINARY)) == NULL)
-		st_fail("Can't open mix file '%s': %s", 
-			mfile, strerror(errno));
-	ft->filename = mfile;
-#if	defined(DUMB_FILESYSTEM)
-	ft->seekable = 0;
-#else
-	ft->seekable = (filetype(fileno(informat.fp)) == S_IFREG);
-#endif
-
-	optind++;
-
-	/* Get output format options */
-	ft = &outformat;
-	doopts(argc, argv);
-
-	writing = 1;
-	if (writing) {
-	    /* Get output file */
-	    if (optind >= argc)
-		usage("No output file?");
-	    ofile = argv[optind];
-	    ft->filename = ofile;
-
-	    /* Move past filename */
-	    optind++;
-
-	    /* Hold off on opening file until the very last minute.
-	     * This allows us to verify header in input files are
-	     * what they should be and parse effect command lines.
-	     * That way if anything is found invalid, we will abort
-	     * without truncating any existing file that has the same
-	     * output filename.
-	     */
-
-	} /* end if writing */
-
-	/* Check global arguments */
-
-	/* negative volume is phase-reversal */
-	if (dovolume && volume < 0.0)
-	    st_report("Volume adjustment is negative.  This will result in a phase change\n");
-	
-	/* 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 (! mixformat.filetype) {
-		if ((mixformat.filetype = strrchr(mfile, LASTCHAR)) != NULL)
-			mixformat.filetype++;
-		else
-			mixformat.filetype = mfile;
-		if ((mixformat.filetype = strrchr(mixformat.filetype, '.')) != NULL)
-			mixformat.filetype++;
-		else /* Default to "auto" */
-			mixformat.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 and mix comments to filenames. 
-	 * The output comment will be assigned when the informat 
-	 * structure is copied to the outformat. 
-	 */
-	informat.comment = informat.filename;
-	mixformat.comment = mixformat.filename;
-
-	process();
-	statistics();
-	return(0);
-}
-
-#ifdef HAVE_GETOPT_H
-char *getoptstr = "+r:v:t:c:hsuUAagbwlfdDxV";
-#else
-char *getoptstr = "r:v:t:c:hsuUAagbwlfdDxV";
-#endif
-
-static void doopts(int argc, char **argv)
-{
-	int c;
-	char *str;
-
-	while ((c = getopt(argc, argv, getoptstr)) != -1) {
-		switch(c) {
-		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
-				st_fail("-r must be given a positive integer");
-			break;
-		case 'v':
-			if (! ft) usage("-v");
-			str = optarg;
-			if ((! sscanf(str, "%lf", &volume)) ||
-					(volume <= 0))
-				st_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))
-				st_fail("-c must be given a number");
-			break;
-		case 'b':
-			if (! ft) usage("-b");
-			ft->info.size = ST_SIZE_BYTE;
-			break;
-		case 'w':
-			if (! ft) usage("-w");
-			ft->info.size = ST_SIZE_WORD;
-			break;
-		case 'l':
-			if (! ft) usage("-l");
-			ft->info.size = ST_SIZE_DWORD;
-			break;
-		case 'f':
-			if (! ft) usage("-f");
-			ft->info.size = ST_SIZE_FLOAT;
-			break;
-		case 'd':
-			if (! ft) usage("-d");
-			ft->info.size = ST_SIZE_DOUBLE;
-			break;
-		case 'D':
-			if (! ft) usage("-D");
-			ft->info.size = ST_SIZE_IEEE;
-			break;
-
-		case 's':
-			if (! ft) usage("-s");
-			ft->info.encoding = ST_ENCODING_SIGN2;
-			break;
-		case 'u':
-			if (! ft) usage("-u");
-			ft->info.encoding = ST_ENCODING_UNSIGNED;
-			break;
-		case 'U':
-			if (! ft) usage("-U");
-			ft->info.encoding = ST_ENCODING_ULAW;
-			break;
-		case 'A':
-			if (! ft) usage("-A");
-			ft->info.encoding = ST_ENCODING_ALAW;
-			break;
-		case 'a':
-			if (! ft) usage("-a");
-			ft->info.encoding = ST_ENCODING_ADPCM;
-			break;
-		case 'i':
-			if (! ft) usage("-i");
-			ft->info.encoding = ST_ENCODING_IMA_ADPCM;
-			break;
-		case 'g':
-			if (! ft) usage("-g");
-			ft->info.encoding = ST_ENCODING_GSM;
-			break;
-		
-		case 'x':
-			if (! ft) usage("-x");
-			ft->swap = 1;
-			break;
-		
-		case 'V':
-			verbose = 1;
-			break;
-		}
-	}
-}
-
-static void init() {
-
-    /* init files */
-    st_initformat(&informat);
-    st_initformat(&mixformat);
-    st_initformat(&outformat);
-
-    informat.fp        = stdin;
-    mixformat.fp       = NULL;
-    outformat.fp       = stdout;
-    informat.filename  = "input";
-    mixformat.filename  = "mix";
-    outformat.filename = "output";
-}
-
-/* 
- * Process input file -> mix with mixfile -> output file
- *	one buffer at a time
- */
-
-static void process() {
-    LONG result, i, *ibuf, *mbuf, *obuf, ilen=0, mlen=0, olen=0;
-
-    if( st_gettype(&informat) )
-                st_fail("Unknown input file format for '%s'.  Use -t option to override",informat.filename);
-
-    if( st_gettype(&mixformat) )
-                st_fail("Unknown input file format for '%s'.  Use -t option to override",mixformat.filename);
-
-    if (writing)
-        if ( st_gettype(&outformat) )
-                st_fail("Unknown output file format for '%s'.  Use -t option to override",outformat.filename);
-
-    /* Read and write starters can change their formats. */
-    if ((* informat.h->startread)(&informat) == ST_EOF)
-    {
-	st_fail(informat.st_errstr);
-    }
-
-    if (st_checkformat(&informat))
-	st_fail("bad input format");
-    
-    if ((* mixformat.h->startread)(&mixformat) == ST_EOF)
-    {
-	st_fail(mixformat.st_errstr);
-    }
-
-    if (st_checkformat(&mixformat))
-	st_fail("bad input format");
-    
-    if (dovolume)
-	st_report("Volume factor: %f\n", volume);
-    
-    st_report("Input file: using sample rate %lu\n\tsize %s, encoding %s, %d %s",
-	   informat.info.rate, st_sizes_str[informat.info.size], 
-	   st_encodings_str[informat.info.encoding], informat.info.channels, 
-	   (informat.info.channels > 1) ? "channels" : "channel");
-    if (informat.comment)
-	st_report("Input file: comment \"%s\"\n", informat.comment);
-	
-    st_report("Mix file: using sample rate %lu\n\tsize %s, encoding %s, %d %s",
-	   mixformat.info.rate, st_sizes_str[mixformat.info.size], 
-	   st_encodings_str[mixformat.info.encoding], mixformat.info.channels, 
-	   (mixformat.info.channels > 1) ? "channels" : "channel");
-    if (mixformat.comment)
-	st_report("Mix file: comment \"%s\"\n", mixformat.comment);
-
-    /* Expect the formats to have the same sample rate.  Although its
-     * possible to auto-convert the sample rate of one file to match
-     * the other using the rate effect, its easier to tell the user
-     * to figure it out and run sox on the input file seperately to
-     * correct it before hand.
-     */
-    if(informat.info.rate != mixformat.info.rate)
-        st_fail("fail: Input and mix files have different sample rates.\nUse sox to resample one of them.\n");
-
-    /* need to check EFF_REPORT */
-    if (writing) {
-        /*
-         * 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;
-
-	    /* stdout tends to be line-buffered.  Override this */
-	    /* to be Full Buffering. */
-	    if (setvbuf (ft->fp,NULL,_IOFBF,sizeof(char)*BUFSIZ))
-	    {
-	        st_fail("Can't set write buffer");
-	    }
-	 }
-         else {
-
-	     ft->fp = fopen(ofile, WRITEBINARY);
-
-	     if (ft->fp == NULL)
-	         st_fail("Can't open output file '%s': %s", 
-		      ofile, strerror(errno));
-
-	     /* stdout tends to be line-buffered.  Override this */
-	     /* to be Full Buffering. */
-	     if (setvbuf (ft->fp,NULL,_IOFBF,sizeof(char)*BUFSIZ))
-	     {
-	         st_fail("Can't set write buffer");
-	     }
-
-        } /* end of else != stdout */
-#if	defined(DUMB_FILESYSTEM)
-	outformat.seekable = 0;
-#else
-	outformat.seekable  = (filetype(fileno(outformat.fp)) == S_IFREG);
-#endif
-
-	/* FIXME: We are defaulting to using the first file's format
-	 * for the output file. Should compare the two inputs and
-	 * warn user that the output file will use the first input
-	 * file's values.
-	 */
-	st_copyformat(&informat, &outformat);
-	if ((* outformat.h->startwrite)(&outformat) == ST_EOF)
-	{
-	    st_fail(outformat.st_errstr);
-	}
-
-	if (st_checkformat(&outformat))
-	    st_fail("bad output format");
-
-	st_report("Output file: using sample rate %lu\n\tsize %s, encoding %s, %d %s",
-	       outformat.info.rate, st_sizes_str[outformat.info.size], 
-	       st_encodings_str[outformat.info.encoding], outformat.info.channels, 
-	       (outformat.info.channels > 1) ? "channels" : "channel");
-	if (outformat.comment)
-	    st_report("Output file: comment \"%s\"\n", outformat.comment);
-    }
-
-    /* Allocate buffers */
-    ibuf = (LONG *) malloc(BUFSIZ * sizeof(LONG));
-    mbuf = (LONG *) malloc(BUFSIZ * sizeof(LONG));
-    obuf = (LONG *) malloc(BUFSIZ * sizeof(LONG));
-    if((!ibuf) || (!mbuf) || (!obuf))
-    {
-	fprintf(stderr, "Can't allocate memory for buffer (%s)\n", 
-		strerror(errno));
-	return;
-    }
-
-    /* Read initial chunks of input data. */
-    /* Do the input file first */
-    ilen = (*informat.h->read)(&informat, ibuf, (LONG) BUFSIZ);
-    /* Change the volume of this data if needed. */
-    if(dovolume)
-	clipped += volumechange(ibuf, ilen, volume);
-
-    /* Now do the mixfile */
-    mlen = (*mixformat.h->read)(&mixformat, mbuf, (LONG) BUFSIZ);
-    /* Change the volume of this data if needed. */
-    if(dovolume)
-	clipped += volumechange(mbuf, mlen, volume);
-
-    /* mix until both input files are done */
-    while (ilen || mlen) {
-	/* Do the mixing from ibuf and mbuf into obuf. */
-	olen = (ilen > mlen) ? ilen : mlen;
-	for (i=0; i<olen; i++)
-	{
-	    /* initial crude mix that might lose a bit of accuracy */
-	    result = (i<ilen) ? (ibuf[i]/2) : 0;
-	    if (i<mlen) result += mbuf[i]/2;
-	    obuf[i] = result;
-	}
-
-	if (writing && olen)
-	    (* outformat.h->write)(&outformat, obuf, (LONG) olen);
-
-	/* Read another chunk of input data. */
-	ilen = (*informat.h->read)(&informat, 
-		ibuf, (LONG) BUFSIZ);
-
-	/* Change volume of these samples if needed. */
-	if(dovolume)
-	    clipped += volumechange(ibuf, ilen, volume);
-
-	/* Read another chunk of mix data. */
-	mlen = (*mixformat.h->read)(&mixformat, 
-		mbuf, (LONG) BUFSIZ);
-
-	/* Change volume of these samples if needed. */
-	if(dovolume)
-	    clipped += volumechange(ibuf, ilen, volume);
-    }
-
-    /* If closing fails then just warn user instead of exiting.
-     * This is because we are basically done with the files anyways.
-     */
-    if ((* informat.h->stopread)(&informat) == ST_EOF)
-	st_warn(informat.st_errstr);
-    fclose(informat.fp);
-
-    if ((* mixformat.h->stopread)(&mixformat) == ST_EOF)
-	st_warn(mixformat.st_errstr);
-    fclose(mixformat.fp);
-
-    if (writing)
-        if ((* outformat.h->stopwrite)(&outformat) == ST_EOF)
-	    st_warn(outformat.st_errstr);
-    if (writing)
-        fclose(outformat.fp);
-}
-
-/* Guido Van Rossum fix */
-static void statistics() {
-	if (dovolume && clipped > 0)
-		st_report("Volume change clipped %d samples", clipped);
-}
-
-static LONG volumechange(buf, ct, vol)
-LONG *buf;
-LONG ct;
-double vol;
-{
-	double y;
-	LONG *p,*top;
-	LONG clips=0;
-
-	p = buf;
-	top = buf+ct;
-	while (p < top) {
-	    y = vol * *p;
-	    if (y < -2147483647.0) {
-		y = -2147483647.0;
-		clips++;
-	    }
-	    else if (y > 2147483647.0) {
-		y = 2147483647.0;
-		clips++;
-	    }
-	    *p++ = y + 0.5;
-	}
-	return clips;
-}
-
-static int filetype(fd)
-int fd;
-{
-	struct stat st;
-
-	fstat(fd, &st);
-
-	return st.st_mode & S_IFMT;
-}
-
-static char *usagestr = 
-"[ gopts ] [ fopts ] ifile [ fopts ] mixfile [ fopts ] ofile";
-
-static void usage(opt)
-char *opt;
-{
-    int i;
-    
-	fprintf(stderr, "%s: ", myname);
-	if (verbose || !opt)
-		fprintf(stderr, "%s\n\n", st_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, "Supported file s: ");
-	    for (i = 0; st_formats[i].names != NULL; i++) {
-		/* only print the first name */
-		fprintf(stderr, "%s ", st_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 (mixformat.fp)
-		fclose(mixformat.fp);
-	if (outformat.fp) {
-		fclose(outformat.fp);
-		/* remove the output file because we failed, if it's ours. */
-		/* Don't if its not a regular file. */
-		if (filetype(fileno(outformat.fp)) == S_IFREG)
-		    REMOVE(outformat.filename);
-	}
-}