sox.c

Go to the documentation of this file.
00001 /*****************************************************
00002  * Modified code from sox for Scilab to read/write 
00003  * wav files 
00004  *
00005  * July 5, 1991
00006  * Copyright 1991 Lance Norskog And Sundry Contributors
00007  * This source code is freely redistributable and may be used for
00008  * any purpose.  This copyright notice must be maintained. 
00009  * Lance Norskog And Sundry Contributors are not responsible for 
00010  * the consequences of using this software.
00011  * 1999 Copyright ENPC 
00012  *****************************************************/
00013 #include "st.h"
00014 #include <string.h>
00015 
00016 #ifndef _MSC_VER
00017 #include <sys/types.h>
00018 #include <sys/stat.h>
00019 #endif
00020 
00021 #include <ctype.h>
00022 #include <errno.h>
00023 #include "machine.h"
00024 #include "sox.h" 
00025 #include "sciprint.h"
00026 /*-----------------------------------------------------------------------------------*/ 
00027 #define Abs(x) ( ( (x) >= 0) ? (x) : -( x) )
00028 #define Min(x,y) ( ( (x) < (y))  ? (x) : (y) )
00029 struct soundstream informat;
00030 ft_t ft;
00031 /*-----------------------------------------------------------------------------------*/ 
00032 static void checkformat __PARAMS((ft_t ft));
00033 static void cleanup  __PARAMS((void));
00034 static void init  __PARAMS((void));
00035 #ifndef _MSC_VER
00036 static int filetype __PARAMS((int fd));
00037 #endif
00038 /*-----------------------------------------------------------------------------------*/ 
00039 /************************************************************
00040  * loadwave 
00041  * --------
00042  * read a wav file and store results in res
00043  * if flag == 1, res is read 
00044  * if flag == 0, size of res is computed but res is not read
00045  ************************************************************/
00046 int C2F(loadwave)(char * filename,double *res, integer * size_res,integer flag,WavInfo *Wi, integer *ierr)
00047 {
00048   long i,size_max;
00049 #if defined(__alpha)|defined(__ia64__)
00050   int buf[BUFSIZ];
00051 #else
00052   long buf[BUFSIZ];
00053 #endif
00054   int olen;
00055   double *res1;
00056   *ierr=0;
00057   init();
00058   /* Get input format options */
00059   ft = &informat;
00060   ft->ierr=*ierr;
00061   /* Get input file */
00062   if ((ft->fp = fopen(filename, READBINARY)) == NULL)
00063     {
00064       sciprint("Can't open input file '%s': %s\r\n", 
00065                filename, strerror(errno));
00066       *ierr=1;
00067       return 0;
00068     }
00069   ft->filename = filename;
00070 #if defined(_MSC_VER)
00071   informat.seekable  = 1;
00072 #else
00073   informat.seekable  = (filetype(fileno(informat.fp)) == S_IFREG);
00074 #endif
00075   informat.comment = informat.filename;
00076 
00077   /* Read and write starters can change their formats. */
00078   wavstartread(&informat,Wi,flag);
00079   if ( ft->ierr > 0 ) 
00080     {
00081       sciprint("Error while reading \r\n");
00082       *ierr=1;
00083       return 0;
00084     }
00085   checkformat(&informat);
00086   if ( ft->ierr > 0 ) 
00087     {
00088       sciprint("Error while reading \r\n");
00089       *ierr=1;
00090       return 0;
00091     }
00092   if ( flag == 1) 
00093     {
00094       sciprint("Input file: using sample rate %lu\r\n", 
00095                informat.info.rate);
00096       sciprint("\tsize %s, style %s, %d %s\r\n",
00097                sizes[informat.info.size], 
00098                styles[informat.info.style], informat.info.channels, 
00099                (informat.info.channels > 1) ? "channels" : "channel");
00100   }
00101   /* read chunk */
00102   size_max = *size_res ; 
00103   *size_res  = 0;
00104   olen = 1;
00105   res1=res;
00106   while ( olen > 0 )
00107     {
00108       olen = wavread(&informat,buf, (long) BUFSIZ);
00109       if ( ft->ierr > 0 ) 
00110         {
00111           sciprint("Error while reading \r\n");
00112           *ierr=1;
00113           return 0;
00114         }
00115       *size_res += olen ;
00116       if (flag == 1 &&  *size_res > size_max ) 
00117         {
00118           sciprint(" Sorry wav file too big \r\n");
00119           return 0;
00120         }
00122       if (flag == 1) 
00123         for ( i = 0 ; i < olen ; i++ ) 
00124           {
00125             *res1++ = buf[i];
00126           }
00127     }
00128   
00129   fclose(informat.fp);
00130 
00131   if ( flag == 1 ) 
00132     {
00133       for ( i = 0 ; i < *size_res ; i++ ) 
00134         {
00135           if ( informat.info.size /8 == 1 )
00136             res[i] = (res[i]-128)/128;
00137           else 
00138             res[i] = ((res[i])/32768)/65536;
00139         }
00140     }
00141   *ierr= ft->ierr;
00142   return 0 ;
00143 }
00144 /*-----------------------------------------------------------------------------------*/ 
00145 /************************************************************
00146  * savewave 
00147  ************************************************************/
00148 int C2F(savewave)(char * filename,double *res,integer * rate,integer *size_res,integer *nchannels, integer *ierr)
00149 {
00150   long buf[BUFSIZ];
00151   long i,size_max;
00152   int count;
00153   double m,*loc;
00154   *ierr=0;
00155   init();
00156   /* Get input format options */
00157   ft = &informat;
00158   ft->ierr=*ierr;
00159   /* Get input file */
00160   if ((ft->fp = fopen(filename, WRITEBINARY)) == NULL)
00161     {
00162       sciprint("Can't open output file '%s': %s\r\n", 
00163            filename, strerror(errno));
00164       *ierr=1;
00165       return 0;
00166     }
00167 
00168   ft->filename = filename;
00169 #if defined(_MSC_VER)
00170   informat.seekable  = 1;
00171 #else
00172   informat.seekable  = (filetype(fileno(informat.fp)) == S_IFREG);
00173 #endif
00174   informat.comment = informat.filename;
00175   
00176   /* changing the formats. */
00177   informat.info.size = WORDSCI;
00178   informat.info.rate = *rate ;
00179   informat.info.style = SIGN2;
00180   informat.info.channels = *nchannels;
00181 
00182   m=1.0;
00183   /* 
00184   m=res[0];
00185   for ( i = 0 ; i < *size_res ; i++) 
00186     {
00187       if ( Abs(res[i]) > m ) m = Abs(res[i]);
00188     }
00189   */
00190   wavstartwrite(&informat);
00191   if ( ft->ierr > 0 ) 
00192     {
00193       *ierr= ft->ierr;
00194       cleanup();
00195       return 0;
00196     }
00197   /* read chunk */
00198   size_max = *size_res ; 
00199   *size_res  = 0;
00200   count = 0 ;
00201   loc= res;
00202   while ( count < size_max ) 
00203     {
00204       double x;
00205       long int len, num;
00206       len = count + BUFSIZ;
00207       len = ( len > size_max ) ? size_max : len;
00208       for ( i = count ; i < len   ; i++ ) 
00209         {
00210           /* x= v/m*2**(31-1); */
00211           x= (*loc++)/m*2147483647;
00212           buf[i-count ] = (long) x;
00214         }
00215       num = len - count ;
00216       wavwrite(&informat,buf, num );
00217       if ( ft->ierr > 0 ) 
00218         {
00219           *ierr= ft->ierr;
00220           cleanup();
00221           return 0;
00222         }
00223       count = len;
00224     }
00225   wavstopwrite(&informat);
00226   fclose(informat.fp);
00227   res[0] = ((double)(size_max))/((double) (*rate));
00228   *ierr= ft->ierr;
00229   return 0;
00230 }
00231 /*-----------------------------------------------------------------------------------*/ 
00232 void init(void) 
00233 {
00234   /* init files */
00235   informat.info.rate      = 0;
00236   informat.info.size      = -1;
00237   informat.info.style     = -1;
00238   informat.info.channels  = -1;
00239   informat.comment   = NULL;
00240   informat.swap      = 0;
00241   informat.filetype  = "wav";
00242   informat.fp        = stdin;
00243   informat.filename  = "input";
00244 }
00245 /*-----------------------------------------------------------------------------------*/ 
00246 /* 
00247  * Process input file -> effect table -> output file
00248  *      one buffer at a time
00249  */
00250 #if defined(_MSC_VER)
00251 /*int filetype(int fd) { return 0;}*/ /* not used --> not defined */
00252 #else 
00253 int filetype(int fd)
00254 {
00255   struct stat st;
00256   fstat(fd, &st);
00257   return st.st_mode & S_IFMT;
00258 }
00259 #endif
00260 /*-----------------------------------------------------------------------------------*/ 
00261 /* called from util.c:fail */
00262 void cleanup(void)
00263 {
00264   if (informat.fp)
00265     fclose(informat.fp);
00266 }
00267 /*-----------------------------------------------------------------------------------*/ 
00268 /* check that all settings have been given */
00269 static void checkformat(ft_t ft)
00270 {
00271   if (ft->info.rate == 0)
00272     {
00273       sciprint("Sampling rate for %s file was not given\r\n", ft->filename);
00274       ft->ierr=1;
00275       return;
00276     }
00277   if ((ft->info.rate < 100) || (ft->info.rate > 50000))
00278     {
00279       sciprint("Sampling rate %lu for %s file is bogus\r\n", 
00280            ft->info.rate, ft->filename);
00281       ft->ierr=1;
00282       return;
00283     }
00284 
00285   if (ft->info.size == -1)
00286     {
00287       sciprint("Data size was not given for %s file\r\n", ft->filename);
00288       ft->ierr=1;
00289       return;
00290     }
00291   if (ft->info.style == -1 && ft->info.size != FLOATSCI)
00292     {
00293       sciprint("Data style was not given for %s file\r\n", ft->filename);
00294       ft->ierr=1;
00295       return;
00296     }
00297   /* it's so common, might as well default */
00298   if (ft->info.channels == -1)
00299     ft->info.channels = 1;
00300 }
00301 /*-----------------------------------------------------------------------------------*/ 
00302 
00303 

Generated on Sun Mar 4 15:04:00 2007 for Scilab [trunk] by  doxygen 1.5.1