📄 shorten.c
字号:
/******************************************************************************Copyright (C) 1992,1993 Tony RobinsonPermission is granted to use this software for non-commercial purposes.Explicit permission must be obtained from the author to use this softwarefor commercial purposes.This software carries no warranty, expressed or implied. The user assumesall risks, known or unknown, direct or indirect, which involve this softwarein any way.Dr Tony RobinsonCambridge University Engineering DepartmentTrumpington Street, Cambridge, CB2 1PZ, UK.ajr@eng.cam.ac.uk voice: +44-223-332815******************************************************************************//* SAL --- Inserted (unsigned long) before first argument in all calls to uvar_put and ulong_put.*/# include <math.h># include <stdio.h># include <setjmp.h># include <util/fob.h># include <util/min.h># include <util/hsgetopt.h># include <sp/shorten/shorten.h>#ifdef fread# undef fread#endif#define fread(a,b,c,d) fob_fread((a),(b),(c),(d)) #ifdef fwrite# undef fwrite#endif#define fwrite(a,b,c,d) fob_fwrite((a),(b),(c),(d)) #ifdef putc# undef putc#endif#define putc(a,b) fob_putc((a),(b))#ifdef getc# undef getc#endif#define getc(a) fob_getc((a))#ifdef unixchar *readmode = "r";char *writemode = "w";#elsechar *readmode = "rb";char *writemode = "wb";#endifchar *argv0 = "shorten";# define ALPHA0 (3.0 / 2.0)# define ALPHA1 M_LN2/* SAL --- put (unsigned long) into macro */# define UINT_PUT(val, nbit, file) \ if(version == 0) uvar_put((unsigned long) val, nbit, file); \ else ulong_put((unsigned long) val, file)# define UINT_GET(nbit, file) \ ((version == 0) ? uvar_get(nbit, file) : ulong_get(file))/* SAL --- put (unsigned long) into macro */# define VAR_PUT(val, nbit, file) \ if(version == 0) var_put((unsigned long) val, nbit - 1, file); \ else var_put((unsigned long) val, nbit, file)int init_offset(long **offset, int nchan, int nblock, int ftype) { long mean = 0; int chan, i; /* initialise offset */ switch(ftype) { case TYPE_AU: case TYPE_S8: case TYPE_S16HL: case TYPE_S16LH: mean = 0; break; case TYPE_U8: mean = 0x80; break; case TYPE_U16HL: case TYPE_U16LH: mean = 0x8000; break; default: update_exit_sd(1, "unknown file type: %d\n", ftype); } for(chan = 0; chan < nchan; chan++) for(i = 0; i < nblock; i++) offset[chan][i] = mean; return(mean);}int shorten(FOB *stdi, FOB *stdo, int argc, char **argv) { static char* copyright = "Copyright (C) 1992,1993 Tony Robinson\n"; long **buffer, *buffer1, **offset; long default_offset; int version = FORMAT_VERSION, extract = 0, bitshift = 0; int hiloint = 1, hilo = !(*((char*) &hiloint)); int ftype = hilo ? TYPE_S16HL : TYPE_S16LH; char *magic = MAGIC, *filenamei = NULL, *filenameo = NULL; char *tmpfilename = NULL, *minusstr = "-", *filesuffix = ".shn"; FOB *filei, *fileo; int blocksize = DEFAULT_BLOCK_SIZE, nchan = DEFAULT_NCHAN; int i, chan, nwrap, nskip = DEFAULT_NSKIP, ndiscard = DEFAULT_NDISCARD; int *qlpc = NULL, maxnlpc = DEFAULT_MAXNLPC, nmean = DEFAULT_NMEAN; int maxresn = DEFAULT_MAXBITRATE, quanterror = DEFAULT_QUANTERROR; int nfilename; /* this block just processes the command line arguments */ { int c; hs_resetopt();/* while((c = hs_getopt(argc, argv, "a:b:c:d:hm:p:r:t:xv:")) != -1) */ while((c = hs_getopt(argc, argv, "a:b:c:d:hm:p:t:xv:")) != -1) switch(c) { case 'a': if((nskip = atoi(hs_optarg)) < 0) usage_exit(1); break; case 'b': if((blocksize = atoi(hs_optarg)) <= 0) usage_exit(1); break; case 'c': if((nchan = atoi(hs_optarg)) <= 0) usage_exit(1); break; case 'd': if((ndiscard = atoi(hs_optarg)) < 0) usage_exit(1); break; case 'h': usage_exit(-1); break; case 'm': if((nmean = atoi(hs_optarg)) < 0) usage_exit(1); break; case 'p': maxnlpc = atoi(hs_optarg); if(maxnlpc < 0 || maxnlpc > MAX_LPC_ORDER) usage_exit(1); break; case 'q': if((quanterror = atoi(hs_optarg)) < 0) usage_exit(1); break; case 'r': if((maxresn = atoi(hs_optarg)) < 0) usage_exit(1); break; case 't': if (!strcmp(hs_optarg, "au")) ftype = TYPE_AU; else if(!strcmp(hs_optarg, "s8")) ftype = TYPE_S8; else if(!strcmp(hs_optarg, "u8")) ftype = TYPE_U8; else if(!strcmp(hs_optarg, "s16")) ftype = hilo ? TYPE_S16HL : TYPE_S16LH; else if(!strcmp(hs_optarg, "u16")) ftype = hilo ? TYPE_U16HL : TYPE_U16LH; else if(!strcmp(hs_optarg, "s16x"))ftype = hilo ? TYPE_S16LH : TYPE_S16HL; else if(!strcmp(hs_optarg, "u16x"))ftype = hilo ? TYPE_U16LH : TYPE_U16HL; else if(!strcmp(hs_optarg, "s16hl"))ftype = TYPE_S16HL; else if(!strcmp(hs_optarg, "u16hl"))ftype = TYPE_U16HL; else if(!strcmp(hs_optarg, "s16lh"))ftype = TYPE_S16LH; else if(!strcmp(hs_optarg, "u16lh"))ftype = TYPE_U16LH; else usage_exit(1); break; case 'v': version = atoi(hs_optarg); if(version < 0 || version > FORMAT_VERSION + 1) usage_exit(1); break; case 'x': extract = 1; break; case '?': usage_exit(1); break; } } if(maxnlpc >= blocksize) usage_exit_s(1, "the predictor order must be less than the block size\n"); /* this chunk just sets up the input and output files */#ifdef STANDALONE nfilename = argc - hs_optind; switch(nfilename) { case 0: filenamei = minusstr; filenameo = minusstr; break; case 1: { int oldfilelen, suffixlen, maxlen; filenamei = argv[argc - 1]; oldfilelen = strlen(filenamei); suffixlen = strlen(filesuffix); maxlen = oldfilelen + suffixlen; tmpfilename = pmalloc((ulong) (maxlen + 1)); strcpy(tmpfilename, filenamei); if(extract) { int newfilelen = oldfilelen - suffixlen; if(strcmp(filenamei + newfilelen, filesuffix)) usage_exit_sss(1,"file name does not end in %s: %s\n", filesuffix, filenamei); tmpfilename[newfilelen] = '\0'; } else strcat(tmpfilename, filesuffix); filenameo = tmpfilename; break; } case 2: filenamei = argv[argc - 2]; filenameo = argv[argc - 1]; break; default: usage_exit(1); } if(strcmp(filenamei, minusstr)) { if((filei = fopen(filenamei, readmode)) == NULL) usage_exit_ss(1, "can't open: %s\n", filenamei); } else filei = stdi; if(strcmp(filenameo, minusstr)) { if((fileo = fopen(filenameo, writemode)) == NULL) usage_exit_ss(1, "can't open: %s\n", filenameo); } else fileo = stdo;#else fileo = stdo; filei = stdi;#endif /* discard header on input file - can't rely on fseek() here */ if(ndiscard != 0) { char discardbuf[BUFSIZ]; for(i = 0; i < ndiscard / BUFSIZ; i++) if(fread(discardbuf, BUFSIZ, 1, filei) != 1) usage_exit_s(1, "EOF on input when discarding header\n"); if(ndiscard % BUFSIZ != 0) if(fread(discardbuf, ndiscard % BUFSIZ, 1, filei) != 1) usage_exit_s(1, "EOF on input when discarding header\n"); } if(!extract) { float alpha; int nread; nwrap = MAX(NWRAP, maxnlpc); /* grab some space for the input buffers */ buffer = long2d((ulong) nchan, (ulong) (blocksize + nwrap)); buffer1 = (long*) pmalloc((ulong) (blocksize * sizeof(*buffer1))); offset = long2d((ulong) nchan, (ulong) nmean); for(chan = 0; chan < nchan; chan++) { for(i = 0; i < nwrap; i++) buffer[chan][i] = 0; buffer[chan] += nwrap; } if(maxnlpc > 0) qlpc = (int*) pmalloc((ulong) (maxnlpc * sizeof(*qlpc))); default_offset = init_offset(offset, nchan, nmean, ftype); /* write magic number */ if(fwrite(magic, strlen(magic), 1, fileo) != 1) usage_exit_s(1, "could not write the magic number\n"); /* write version number */ if(putc(version, fileo) == EOF) usage_exit_s(1, "EOF when writing version number\n"); /* initialise the variable length mode */ var_put_init(fileo); /* put file type and number of channels */ UINT_PUT(ftype, TYPESIZE, fileo); UINT_PUT(nchan, CHANSIZE, fileo); /* put blocksize if version > 0 */ if(version == 0) { alpha = ALPHA0; if(blocksize != DEFAULT_BLOCK_SIZE) { uvar_put((ulong) FN_BLOCKSIZE, FNSIZE, fileo); UINT_PUT(blocksize, (int) (log((double) DEFAULT_BLOCK_SIZE) / M_LN2), fileo); } } else { alpha = ALPHA1; UINT_PUT(blocksize, (int) (log((double) DEFAULT_BLOCK_SIZE) / M_LN2), fileo); UINT_PUT(maxnlpc, LPCQSIZE, fileo); UINT_PUT(nmean, 0, fileo); UINT_PUT(nskip, NSKIPSIZE, fileo); for(i = 0; i < nskip; i++) { int byte = getc(filei); if(byte == EOF) usage_exit_s(1, "EOF when reading header\n"); uvar_put((ulong) byte, XBYTESIZE, fileo); } } while((nread = fread_type(buffer, ftype, nchan, blocksize, filei)) != 0) { /* put blocksize if changed */ if(nread != blocksize) { uvar_put((ulong) FN_BLOCKSIZE, FNSIZE, fileo); UINT_PUT(nread, (int) (log((double) blocksize) / M_LN2), fileo); blocksize = nread; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -