?? shorten.c
字號:
/******************************************************************************* ** Copyright (C) 1992-1997 Tony Robinson and SoftSound Limited ** ** See the file LICENSE for conditions on distribution and usage ** *******************************************************************************//* * $Id: shorten.c,v 1.22 2003/01/11 01:28:15 jason Exp $ */#ifdef _WINDOWS#include <windows.h>#endif#include <math.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#ifdef MSDOS#include <io.h>#include <fcntl.h>#ifdef MSDOS_DO_TIMING#include <time.h>#endif#else#ifndef _WINDOWS#include <unistd.h>#endif#include <errno.h>#endif#include <setjmp.h>#include "shorten.h"#ifdef HAVE_CONFIG_H#include "config.h"#endif#define V2LPCQOFFSET (1 << LPCQUANT);#define UINT_PUT(val, nbit, file) \ if(version == 0) uvar_put((ulong) val, nbit, file); \ else ulong_put((ulong) val, file)#define UINT_GET(nbit, file) \ ((version == 0) ? uvar_get(nbit, file) : ulong_get(file))#define VAR_PUT(val, nbit, file) \ if(version == 0) var_put((ulong) val, nbit - 1, file); \ else var_put((ulong) val, nbit, file)#define FILESUFFIX ".shn"#define WAVESUFFIX ".wav"extern char *exitmessage;char *readmode = "rb";char *writemode = "wb";char *argv0 = NULL;char *filenameo = NULL;int getc_exit_val;int Pass=0;int saw_e_op = FALSE;int saw_i_op = FALSE;int saw_k_op = FALSE;int saw_s_op = FALSE;int saw_S_op = FALSE;int saw_x_op = FALSE;ulong bytes_read = 0;FILE *fileo = NULL;/* globals for seek table */ulong SampleNumber=0;ulong SHNFilePosition=0;ulong SHNLastBufferReadPosition=0;ushort SHNByteGet=0;ushort SHNBufferOffset=0;ushort SHNBitPosition=0;ulong SHNGBuffer=0;ulong LastBufferReadPosition;int ReadingFunctionCode=FALSE;int WriteSeekTable=TRUE;int WriteWaveFile=FALSE;int AppendSeekInfo=FALSE;slong CBuf_0_Minus1 = 0;slong CBuf_0_Minus2 = 0;slong CBuf_0_Minus3 = 0;slong CBuf_1_Minus1 = 0;slong CBuf_1_Minus2 = 0;slong CBuf_1_Minus3 = 0;slong Offset_0_0 = 0;slong Offset_0_1 = 0;slong Offset_0_2 = 0;slong Offset_0_3 = 0;slong Offset_1_0 = 0;slong Offset_1_1 = 0;slong Offset_1_2 = 0;slong Offset_1_3 = 0;typedef struct tag_TSeekTableHeader{ uchar data[SEEK_HEADER_SIZE];}TSeekTableHeader;typedef struct tag_TSeekTableTrailer{ uchar data[SEEK_TRAILER_SIZE];}TSeekTableTrailer;typedef struct tag_TSeekEntry{ uchar data[SEEK_ENTRY_SIZE];}TSeekEntry;/* old way, kept for reference. (changed because some compilers apparently don't support #pragma pack(1))typedef struct tag_TSeekTableHeader{ char Signature[4]; ulong Version; unsigned long SHNFileSize;}TSeekTableHeader;typedef struct tag_TSeekTableTrailer{ unsigned long SeekTableSize; char Signature[8];}TSeekTableTrailer;typedef struct tag_TSeekEntry{ unsigned long SampleNumber; unsigned long SHNFileByteOffset; unsigned long SHNLastBufferReadPosition; unsigned short SHNByteGet; unsigned short SHNBufferOffset; unsigned short SHNFileBitOffset; unsigned long SHNGBuffer; unsigned short SHNBitShift; long CBuf0[3]; long CBuf1[3]; long Offset0[4]; long Offset1[4];}TSeekEntry;*/void init_offset(slong **offset,int nchan,int nblock,int ftype){ slong mean = 0; int chan, i; /* initialise offset */ switch(ftype) { case TYPE_AU1: case TYPE_S8: case TYPE_S16HL: case TYPE_S16LH: case TYPE_ULAW: case TYPE_AU2: case TYPE_AU3: case TYPE_ALAW: mean = 0; break; case TYPE_U8: mean = 0x80; break; case TYPE_U16HL: case TYPE_U16LH: mean = 0x8000; break; default: update_exit(1, "unknown file type: %d\n", ftype); } for(chan = 0; chan < nchan; chan++) for(i = 0; i < nblock; i++) offset[chan][i] = mean;}float Satof(char *string){ int i, rval = 1; /* this should have tighter checking */ for(i = 0; i < (int) strlen(string) && rval == 1; i++) if(string[i] != '.' && (string[i] < '0' || string[i] > '9')) usage_exit(1, "non-parseable float: %s\n", string); return((float) atof(string));}float* parseList(char *maxresnstr,int nchan){ int nval; char *str, *floatstr; float *floatval; /* copy maxresnstr to temporary space, str */ str = malloc(strlen(maxresnstr) + 1); strcpy(str, maxresnstr); /* grab space for the floating point parses */ floatval = pmalloc((ulong) (nchan * sizeof(*floatval))); /* loop for all floats in the arguement */ floatstr = strtok(str, ","); floatval[0] = Satof(floatstr); for(nval = 1; (floatstr = strtok(NULL, ",")) != NULL && nval < nchan;nval++) floatval[nval] = Satof(floatstr); for(; nval < nchan; nval++) floatval[nval] = floatval[nval - 1]; free(str); return(floatval);}#ifdef _WINDOWS/* Function to check whether shorten should abort, when running as a windows program */static void CheckWindowsAbort(void){#ifndef WIN32 /* If we are not in Win32, we need to put in a Windows message handler to ** allow 'multi tasking' to continue. ** WIN32 (Windows 95 and NT) does not need to do this, as proper preemptive ** multitasking & threading is implemented */ MSG localMessage; while (PeekMessage(&localMessage,NULL,0,0,PM_REMOVE)) { TranslateMessage(&localMessage); DispatchMessage(&localMessage); }#endif#ifdef WINDOWS_ABORT_ALLOWED /* If abort is allowed, see if the abort flag has been set: */ { extern int abortFlag; if (abortFlag) { /* If the abort flag is set, it means we should terminate processing */ usage_exit(-2, PACKAGE " stopped by user\n"); } }#endif}#endif#if defined(MSDOS) || defined(_WINDOWS)int _export __stdcall _CallShorten(int argc, char **argv, char *errorString, int errorStringLength){ exitmessage=errorString; return(shorten(stdin,stdout,argc,argv));}#endifulong uchar_to_ulong_le(uchar * buf)/* converts 4 bytes stored in little-endian format to a ulong */{ return (ulong)((buf[3] << 24) + (buf[2] << 16) + (buf[1] << 8) + buf[0]);}void ulong_to_uchar_le(uchar * buf,ulong num)/* converts a ulong to 4 bytes stored in little-endian format */{ uchar tmp[4]; tmp[0] = (uchar)(num); tmp[1] = (uchar)(num >> 8); tmp[2] = (uchar)(num >> 16); tmp[3] = (uchar)(num >> 24); buf[0] = tmp[0]; buf[1] = tmp[1]; buf[2] = tmp[2]; buf[3] = tmp[3];}void long_to_uchar_le(uchar * buf,slong num){ ulong_to_uchar_le(buf,(ulong)num);}void ushort_to_uchar_le(uchar * buf,ushort num)/* converts a ushort to 2 bytes stored in little-endian format */{ uchar tmp[2]; tmp[0] = (uchar)(num); tmp[1] = (uchar)(num >> 8); buf[0] = tmp[0]; buf[1] = tmp[1];}BOOL FileContainsSeekInfo(FILE *filei){ char SeekSignature[9]="SHNAMPSK"; char Buffer[9]=" "; long InitialPosition=ftell(filei); fseek(filei,-8,SEEK_END); fread(Buffer,1,8,filei); fseek(filei,InitialPosition,SEEK_SET); if(0==memcmp(SeekSignature,Buffer,8)) return TRUE; else return FALSE;}void RemoveSeekInfo(char *filename){#ifdef HAVE_TRUNCATE ulong SHNFileSize,sktSize; TSeekTableTrailer Trailer; FILE *f; f=fopen(filename,"rb"); if(!f) usage_exit(1,"failure opening '%s': %s\n",filename,strerror(errno)); fseek(f,0,SEEK_END); SHNFileSize=(ulong)ftell(f); fseek(f,-SEEK_TRAILER_SIZE,SEEK_END); fread(&Trailer,SEEK_TRAILER_SIZE,1,f); fclose(f); sktSize = uchar_to_ulong_le(Trailer.data); SHNFileSize -= sktSize; fprintf(stderr,"removing seek table from file '%s'\n",filename); if (0 != truncate(filename,SHNFileSize)) fprintf(stderr,"error: could not truncate file: %s\n",strerror(errno));#else fprintf(stderr,"error: Your system does not seem to support the truncate() function.\n"); fprintf(stderr," Please report this error to <shnutils@freeshell.org>.\n");#endif}void check_conflicting_options(){ if (saw_e_op && saw_i_op) usage_exit(1, "cannot use -e with -i\n"); if (saw_x_op && saw_k_op) usage_exit(1, "cannot use -x with -k\n"); if (saw_e_op && saw_x_op) usage_exit(1, "cannot use -e with -x\n"); if (saw_e_op && saw_k_op) usage_exit(1, "cannot use -e with -k\n"); if (saw_i_op && saw_x_op) usage_exit(1, "cannot use -i with -x\n"); if (saw_i_op && saw_k_op) usage_exit(1, "cannot use -i with -k\n"); if (saw_s_op && saw_S_op) usage_exit(1, "cannot use -s with -S\n"); if (saw_x_op && saw_s_op) usage_exit(1, "cannot use -x with -s\n"); if (saw_x_op && saw_S_op) usage_exit(1, "cannot use -x with -S\n"); if (saw_k_op && saw_s_op) usage_exit(1, "cannot use -k with -s\n"); if (saw_k_op && saw_S_op) usage_exit(1, "cannot use -k with -S\n");}int shorten(FILE *stdi, FILE *stdo,int argc,char **argv){ TSeekTableHeader SeekTableHeader; TSeekTableTrailer SeekTableTrailer; slong **buffer, **offset; slong lpcqoffset = 0; int version = MAX_SUPPORTED_VERSION, extract = 0, lastbitshift = 0, bitshift = 0, want_seeking = 1; int hiloint = 1, hilo = !(*((char*) &hiloint)); int ftype = TYPE_EOF; char *magic = MAGIC, *filenamei = NULL, *filenamei_orig = NULL; char *tmpfilename = NULL; char *maxresnstr = DEFAULT_MAXRESNSTR; FILE *filei = 0; 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 = UNDEFINED_UINT; int quanterror = DEFAULT_QUANTERROR, minsnr = DEFAULT_MINSNR, nfilename; int ulawZeroMerge = 0; slong datalen = -1; Iff_Header *wavhdr = NULL; char *minusstr = "-"; extern char *hs_optarg; extern int hs_optind; ulong WriteCount=0; char SeekTableFilename[MAX_PATH]; FILE *SeekTableFile=0;#ifdef MSDOS#ifdef MSDOS_DO_TIMING clock_t startTime, endTime; startTime = clock();#endif#endif argv0 = (0 == strrchr(argv[0],'/')) ? argv[0] : strrchr(argv[0],'/') + 1;#ifdef _WINDOWS/* Need to set the FILE pointers to null, so we know if they have to be closed on abort */ filei = fileo = NULL; /* Now we need to set up the error handler for Windows */ { extern jmp_buf exitenv; int retVal; if ((retVal = setjmp(exitenv)) != 0) { /* If an error, make sure (at least) that files are closed. fileo will already have been closed in basic_exit(); Plugging of memory leaks will be dealt with in a future release */ if (filei) fclose(filei); return retVal; } }
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -