📄 oper.c
字号:
/* Version 1.4 - 02.Jul.99 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ OPER.C ~~~~~~ Description: ~~~~~~~~~~~~ Program for implementing simple arithmetic operations over two binary speech files (+, -, *, and /): A*file1 + B*file2 + C A*file1 - B*file2 + C A*file1 * B*file2 + C A*file1 / B*file2 + C Supported data types are short (in both decimal and hex formats) and, in the future, float. Both files have to be of the same type (short, float, etc). This program can also add the files with a delay between them. This delay may be fixed or random, as specified in the command line. The default is no delay. *** NOTE: *** Not fully tested: need to be thoroughly tested with -, *, and /. Usage: ~~~~~~ $ OPER [-options] A file1 op B file2 C resfil [BlockSize [1stBlock [NoOfBlocks [DataType]]]]] where: A is the multiplier for the first file samples (dB or linear) file1 is the first file name; B is the multiplier for the 2nd file samples (dB or linear) file2 is the second file name; C is the constant to add (linear *only*!) BlockSize is the Block size, in samples [default: 256 samples]; 1stBlock is the stating block [default: 1st block]; NoOfBlocks the number of blocks to be operated [default: all]; DataType if the file data type (float, long, ...) [default: short]; Options: -q operate quietly - only report total no.of differences -delay n n is the number of samples to delay. If n>0, the first file should be delayed in relation to the second file (samples from file 1 should be skipped). n<0, on the other hand, means that the 2nd file is who should be delayed (i.e., have samples skipped). -random n instructs the program to apply a random delay to the files (as defined for -delay) but no longer than n *seconds*. It is internally converted to number of samples. Default is no delay. -gain s Specify that gains A, B are given either in dB (s=dB) *power* or in linear format (s=linear). Default is linear. NOTE THAT the offset C is *always* linear. -size # trim output filesize by the size of 1st file (#=1), of the 2nd file (#=2), the longest of both (#=3) or the shortest of both (#=0) [default: 0] -round Uses rounding after integer operations [default] -trunc Uses truncation after integer operations -float display float numbers -double display double numbers -short display short numbers [default] -long display long numbers Original Author: ~~~~~~~~~~~~~~~~ Simao Ferraz de Campos Neto COMSAT Labs Tel: +1-301-428-4516 22300 Comsat Drive Fax: +1-301-428-4534 Clarksburg Md 20874 - USA E-mail: <simao@ctd.comsat.com> History: ~~~~~~~~ 06/Jul/1995 v1.0 Created 30/Aug/1995 v1.1 RAND_MAX is not available in non-ANSI C compilers; added a "hard-definition" if not defined by stdlib.h <simao>. 25/Sep/1995 v1.2 Added option to trim by the size of the largest of the input files. Added overflow protection to trim case. 27/May/1997 v1.3 Increased maximum file name size <simao> 02/Jul/1999 v1.4 Added hook to allow compilation with MS Visual C Compiler V.6 [aliased sleep to _sleep()] and added option for truncation instead of rounding <simao>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*//* includes in general */#include <stdio.h>#include <stdlib.h>#include <math.h>#include <string.h> /* for memset() */#include <ctype.h>#include "ugstdemo.h"/* ... Includes for O.S. specific headers ... */#if defined(MSDOS)#include <fcntl.h>#include <io.h>#include <sys\stat.h>#elif defined(VMS)#include <perror.h>#include <file.h>#include <stat.h>#else /* Unix */#include <sys/stat.h>#include <unistd.h> /* Specific for read/write/lseek */#endif/* Define specific function call */#ifdef _MSC_VER /* Dirty trick to circumvent problems in MSCVC */#define sleep _sleep#endif/* Define maximum random number generator output, if not defined */#ifndef RAND_MAX#if defined(sun) || defined(vms)#define RAND_MAX 2147483647 /* 2**31-1, as per the man page */#else#define RAND_MAX 32767 /* Def. valid for gcc, although gcc has RAND_MAX */#endif#endif/* Function prototypes */void display_usage ARGS((void));/* Choose delay to improve seed to random number generator */#ifndef USE_IT#define USE_IT 1#endif/* Pseudo-functions */#define dB2linear(x) pow((double)10., (x)/(double)20.);/* * -------------------------------------------------------------------------- * ... Display usage of program ... * Simao * -------------------------------------------------------------------------- */#define P(x) printf xvoid display_usage(){ P(("OPER.C - Version 1.4 of 2/Jul/1999 \n\n")); P(("Program for implementing simple arithmetic operations over two\n")); P(("*binary* speech files (+, -, *, and /):\n")); P((" A*file1 [+-*/] B*file2 + C\n")); P(("Supported data types are short (in both decimal and hex formats) \n")); P(("and, in the future, float. Both files have to be of the same \n")); P(("type (short, float, etc).\n")); P(("This program can also add the files with a fixed or a random delay\n")); P(("between them, as specified in the command line [Default: no delay]\n")); P(("\n")); P(("Usage:\n")); P(("$ OPER [-options] A file1 op B file2 C resfil\n")); P((" [BlockSize [1stBlock [NoOfBlocks [DataType]]]]]\n")); P((" A multiplier for the first file samples (dB or linear)\n")); P((" file1 first file name;\n")); P((" B multiplier for the second file samples (dB or linear)\n")); P((" file2 second file name;\n")); P((" C constant to add (linear *only*!)\n")); P((" BlockSize block size, in samples [default: 256 samples];\n")); P((" 1stBlock starting block [default: 1st block];\n")); P((" NoOfBlocks number of blocks to be operated [default: all];\n")); P((" DataType file data type (float, long, ...)[default: short];\n")); P(("\n")); P(("Options:\n")); P(("-q operate quietly\n")); P(("-delay n n is the number of samples to delay. If n>0,\n")); P((" the first file should be delayed in relation to the\n")); P((" second file (samples from file 1 should be skipped). \n")); P((" n<0, on the other hand, means that the 2nd file \n")); P((" is who should be delayed (i.e., have samples skipped).\n")); P(("-random n instructs the program to apply a random delay to the \n")); P((" files (as defined for -delay) but no longer than \n")); P((" n *seconds*. It is internally converted to number of\n")); P((" samples. Default is no delay.\n")); P(("-gain s specify that gains A, B are given either in dB (s=dB) \n")); P((" *power* or in linear format (s=linear). Default is \n")); P((" linear. NOTE THAT the offset C is *always* linear. \n")); P(("-size # trim output filesize by the size of 1st file (#=1), \n")); P((" of the 2nd file (#=2), the longest of both (#=3) \n")); P((" or the shortest of both (#=0) [default: 0]\n")); P(("-round Uses rounding after integer operations [default]\n")); P(("-trunc Uses truncation after integer operations\n")); P(("-float display float numbers\n")); P(("-double display double numbers\n")); P(("-short display short numbers [default]\n")); P(("-long display long numbers\n")); /* Quit program */ exit(-128);}#undef P/* ....................... end of display_usage() ...........................*//* .............. definition of the operation functions ................... */#define FUNCS 4double add(x,y)double x,y;{ return x+y;}double sub(x,y)double x,y;{ return x-y;}double mult(x,y)double x,y;{ return x*y;}double divide(x,y)double x,y;{ return y<1E-38? 1E+38:x/y;}/* ................... operation functions ......................... *//* ------------------------------------------------------------------------- Operate over short int files ------------------------------------------------------------------------- */long operate_shorts(File1,File2,File3,fh1,fh2,fh3,N,N1,N2, A,B,C,oper_f,trim_by,round)char *File1,*File2,*File3, trim_by;int fh1,fh2,fh3;long N,N1,N2;double A, B, C, round, (*oper_f)();{ long i,j,l,k,saved=0; short *a, *b; register double tmp; /* Allocate memory for data vectors */ if ((a=(short *)calloc(N,sizeof(short)))==NULL) return -1; if ((b=(short *)calloc(N,sizeof(short)))==NULL) { free(a); return -1; } /* Read data in chuncks, procecess & save */ for (i = j = 0; i < N2; i++, j = 0) { /* Reset buffers */ memset(a,0,N*sizeof(short)); memset(b,0,N*sizeof(short)); if ((l = read(fh1, a, sizeof(short) * N) / sizeof(short)) >= 0 && (k = read(fh2, b, sizeof(short) * N) / sizeof(short)) >= 0) while (j < l && j < k) { tmp = oper_f(A * (double)a[j], B * (double)b[j]) + C + round; b[j] = (short)(tmp > 32767 ? 32767 : (tmp < -32768 ? -32768 : tmp)); j++; } else { if (l < 0) { KILL(File1, 5); } else if (k<0) { KILL(File2, 6); } else break; } /* Flush if it is the case */ if (trim_by==1) for (;j<l;j++) { tmp = (A * (double)a[j] + C + round); b[j] = (short)(tmp > 32767 ? 32767 : (tmp < -32768 ? -32768 : tmp)); } else if (trim_by==2) for (;j<k;j++) { tmp = (B * (double)b[j] + C + round); b[j] = (short)(tmp > 32767 ? 32767 : (tmp < -32768 ? -32768 : tmp)); } saved += write(fh3, b, sizeof(short) * j) / sizeof(short); } return(saved);}/* ................ end of operate_shorts() ................... *//*============================== */int main(argc, argv) int argc; char *argv[];/*============================== */{ char c[1], Oper[1]; int fh1, fh2, fhr; long N, N1, N2, Prcd=0; long delay=0, start_byte1, start_byte2, samplesize; char File1[150], File2[150], RFile[150]; char TypeOfData = 'I', quiet=0, gain_in_dB = 0; char better_seed=USE_IT, trim_by = 0; static char *trim_str[4]={"shortest", "first", "second", "longest"}; double A=0, B=0, C=0, (*oper_f)(), round=0.5; FILE *f1, *f2, *fr;#ifdef VMS char mrs[15] = "mrs=";#endif /* ......... GET PARAMETERS ......... */ /* Check options */ if (argc < 2)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -