pf_lib.c
来自「LastWave」· C语言 代码 · 共 1,800 行 · 第 1/4 页
C
1,800 行
for(nq=0;nq < qNumber-1;nq++) if(cellArray[nq]->q >= cellArray[nq+1]->q) return PFNotValid; return PFYes;}/* Returns PFYes if pf is valid (meaningful content). It should always be the case after PFInit() has been used once. */int PFIsValid(PartitionFunction pf){ if( (_PFIsValid(pf) != PFYes) ) return PFNotValid; if(pf->qNumber == 0) { if(pf->cellArray != NULL) return PFNotValid; else return PFYes; } if( _PFCellArrayIsValid(pf->cellArray,pf->qNumber,pf->octaveNumber*pf->voiceNumber) != PFYes ) return PFNotValid; return PFYes;}/************************************************* * * Writing a PartitionFunction in ASCII or BINARY format * *************************************************//* The same as fprinf but return PFWriErr on an error */#define PFFPRINTF(exp) if( fprintf exp < 0 ) return PFWriErr/* The same as fwrite but return PFWriErr on an error */#define PFFWRITE(exp,lengh) if( fwrite exp != (size_t) lengh ) return PFWriErr/* All the string constant defined below should be shorter than PFMESSMAXSIZE */#define PFMESSMAXSIZE 50/* Format used while writing double */#define PFDOUBLEWRITEFORMAT " %.15G "/* Format used while reading double */#define PFDOUBLEREADFORMAT "%lG "#define PFMessIdent "partition function 2.0"#define PFMessAsciiFormat "ascii"#define PFMessBinFormat "binary"#define PFMessBigEndian "big endian"#define PFMessLittleEndian "little endian"#define PFMessMethod "method: "#define PFMessAMin "first scale: "#define PFMessOctaveNumber "octaves number: "#define PFMessVoiceNumber "voices number: "#define PFMessIndexMax "maximum index: "#define PFMessSignalSize "source size: "#define PFMessSignalNumber "sources number: "#define PFMessDimension "dimension: "#define PFMessQNumber "q number: "#define PFMessQList "q list: "#define PFMessQ "q: "#define PFMessSTq "sTq: "#define PFMessSTqLogT "sTqLogT: "#define PFMessLogSTq "logSTq: "#define PFMessSTqLogT_sTq "sTqLogT_sTq: "#define PFMessLog2STq "log^2(sTq): "#define PFMessSTqLogT_sTq2 "sTqLogT_sTq^2: "#define PFMessLogSTqSTqLogT_sTq "LogSTqSTqLogT_sTq: "static int PFCellWriteAsciiOneFunc(FILE *fp,const char message[], double *t,int tSize){ int i; assert( fp != NULL ); assert( message != NULL ); assert( t != NULL ); assert( tSize > 0 ); PFFPRINTF((fp,"%s",message)); for(i=0;i < tSize;i++) PFFPRINTF((fp,PFDOUBLEWRITEFORMAT,t[i])); PFFPRINTF((fp,"\n")); return PFYes;}static int PFCellWriteAscii(FILE *fp,PartitionFunctionCell pfc){ assert( fp != NULL && pfc != NULL ); PFFPRINTF((fp,"%s"PFDOUBLEWRITEFORMAT"\n",PFMessQ,pfc->q)); if( PFCellWriteAsciiOneFunc(fp,PFMessSTq,pfc->sTq,pfc->size) != PFYes ) return PFWriErr; if( PFCellWriteAsciiOneFunc(fp,PFMessSTqLogT,pfc->sTqLogT,pfc->size) != PFYes ) return PFWriErr; if( PFCellWriteAsciiOneFunc(fp,PFMessLogSTq,pfc->logSTq,pfc->size) != PFYes ) return PFWriErr; if( PFCellWriteAsciiOneFunc(fp,PFMessSTqLogT_sTq,pfc->sTqLogT_sTq,pfc->size) != PFYes ) return PFWriErr; if( PFCellWriteAsciiOneFunc(fp,PFMessLog2STq,pfc->log2STq,pfc->size) != PFYes ) return PFWriErr; if( PFCellWriteAsciiOneFunc(fp,PFMessSTqLogT_sTq2,pfc->sTqLogT_sTq2,pfc->size) != PFYes ) return PFWriErr; if( PFCellWriteAsciiOneFunc(fp,PFMessLogSTqSTqLogT_sTq,pfc->logSTqSTqLogT_sTq,pfc->size) != PFYes ) return PFWriErr; return PFYes;}int PFWriteAscii(FILE *fp,PartitionFunction pf){ int nq; if( PFIsValid(pf) != PFYes) return PFNotValid; if(fp == NULL) return PFNo; PFFPRINTF((fp,PFMessIdent"\n"PFMessAsciiFormat"\n")); PFFPRINTF((fp,PFMessMethod"%s\n",pf->method)); PFFPRINTF((fp,PFMessAMin PFDOUBLEWRITEFORMAT"\n",pf->aMin)); PFFPRINTF((fp,PFMessOctaveNumber"%d\n",pf->octaveNumber)); PFFPRINTF((fp,PFMessVoiceNumber"%d\n",pf->voiceNumber)); PFFPRINTF((fp,PFMessIndexMax"%d\n",pf->indexMax)); PFFPRINTF((fp,PFMessSignalSize"%d\n",pf->signalSize)); PFFPRINTF((fp,PFMessSignalNumber"%d\n",pf->signalNumber)); PFFPRINTF((fp,PFMessDimension"%d\n",pf->dimension)); PFFPRINTF((fp,PFMessQNumber"%d\n",pf->qNumber)); PFFPRINTF((fp,PFMessQList)); for(nq=0;nq < pf->qNumber;nq++) PFFPRINTF((fp,PFDOUBLEWRITEFORMAT,pf->cellArray[nq]->q)); PFFPRINTF((fp,"\n")); for(nq=0;nq < pf->qNumber;nq++) if( PFCellWriteAscii(fp,pf->cellArray[nq]) != PFYes ) return PFWriErr; return PFYes;}/* Test whether we are running on big endian or little endian */static char PFIsLittleEndian(void) { short unsigned int i; char *c; i = 1; c = (char *) (&i); if (*c == 0) return(PFNo); else return(PFYes);} static int PFWriteBinHeader(FILE *fp,PartitionFunction pf){ PFFWRITE( ((void *)pf, sizeof(struct PartitionFunction)-sizeof(PartitionFunctionCell *), 1,fp),1); return PFYes;}static int PFCellWriteBin(FILE *fp,PartitionFunctionCell pfc){ assert( fp != NULL && pfc != NULL ); assert( pfc->sTq != NULL ); assert( pfc->size > 0 ); PFFWRITE( ((void *) &(pfc->q),sizeof(double),1,fp),1); PFFWRITE( ((void *) &(pfc->size),sizeof(int),1,fp),1); PFFWRITE( ((void *) pfc->sTq,sizeof(double),7*pfc->size,fp),7*pfc->size); return PFYes;}int PFWriteBin(FILE *fp,PartitionFunction pf){ int nq; if( PFIsValid(pf) != PFYes) return PFNotValid; if(fp == NULL) return PFNo; PFFPRINTF((fp,PFMessIdent"\n"PFMessBinFormat"\n")); if( PFIsLittleEndian() == PFYes) {PFFPRINTF((fp,PFMessLittleEndian"\n"));} else {PFFPRINTF((fp,PFMessBigEndian"\n"));} /* Let's write the header */ if( PFWriteBinHeader(fp,pf) != PFYes) return PFWriErr; /* Let's write the cells */ for(nq=0;nq < pf->qNumber;nq++) if( PFCellWriteBin(fp,pf->cellArray[nq]) != PFYes ) return PFWriErr; return PFYes;}/************************************************* * * Reading a PartitionFunction in ASCII or BINARY format * *************************************************//* The same as fscanf but return PFErrFormat on an error */#define PFFSCANF(exp) if( fscanf exp <= 0 ) return PFErrFormat/* The same as fread but return PFReadErr on an error */#define PFFREAD(exp,lengh) if( fread exp != (size_t) lengh ) return PFReadErr/* It reads the q from the stream fp. Enough space is supposed to have been allocated for qArray */static int PFReadAsciiDoubleList(FILE *fp,const char *message,int dSize, double *d){ int i; char format[2*PFMESSMAXSIZE+1]; assert( fp != NULL && message != NULL && d != NULL ); assert( dSize > 0 ); /* We read the first double verifying it is after the corect message */ format[0] = '\0'; strcat(format,message); strcat(format,PFDOUBLEREADFORMAT); PFFSCANF((fp,format,d)); for(i=1;i < dSize;i++) PFFSCANF((fp,PFDOUBLEREADFORMAT,d+i)); return PFYes;}static int PFCellReadAscii(FILE *fp,PartitionFunctionCell pfc){ double q; assert( fp != NULL ); assert( pfc != NULL ); if( PFReadAsciiDoubleList(fp,PFMessQ,1,&q) != PFYes ) return PFErrFormat; if( q != pfc->q ) return PFErrFormat; if( PFReadAsciiDoubleList(fp,PFMessSTq,pfc->size,pfc->sTq) != PFYes ) return PFErrFormat; if( PFReadAsciiDoubleList(fp,PFMessSTqLogT,pfc->size,pfc->sTqLogT) != PFYes ) return PFErrFormat; if( PFReadAsciiDoubleList(fp,PFMessLogSTq,pfc->size,pfc->logSTq) != PFYes ) return PFErrFormat; if( PFReadAsciiDoubleList(fp,PFMessSTqLogT_sTq,pfc->size,pfc->sTqLogT_sTq) != PFYes ) return PFErrFormat; if( PFReadAsciiDoubleList(fp,PFMessLog2STq,pfc->size,pfc->log2STq) != PFYes ) return PFErrFormat; if( PFReadAsciiDoubleList(fp,PFMessSTqLogT_sTq2,pfc->size,pfc->sTqLogT_sTq2) != PFYes ) return PFErrFormat; if( PFReadAsciiDoubleList(fp,PFMessLogSTqSTqLogT_sTq,pfc->size,pfc->logSTqSTqLogT_sTq) != PFYes ) return PFErrFormat; return PFYes;}/* Reading function for the ASCII format */static int PFReadAscii(FILE *fp,PartitionFunction pf){ char methodLine[PFMESSMAXSIZE+PFMETHODSIZE+2]; int nq; int err; double *qArray; assert( fp != NULL && pf != NULL ); /* If pf->cellArray != NULL it means that we are writing on an already used PartitionFunction So we delete the cellArray */ if( pf->cellArray != NULL ) { PFCellArrayDelete(pf->cellArray,pf->qNumber); pf->cellArray = NULL; } if( fgets(methodLine,PFMESSMAXSIZE+PFMETHODSIZE+2,fp) == NULL) return PFReadErr; if( strncmp(methodLine,PFMessMethod,strlen(PFMessMethod)) != 0 ) return PFErrFormat; /* The last character in methodLine is \n we convert it to \0 */ methodLine[strlen(methodLine)-1] = '\0'; strcpy(pf->method,methodLine+strlen(PFMessMethod)); PFFSCANF((fp,PFMessAMin PFDOUBLEREADFORMAT"\n",&pf->aMin)); PFFSCANF((fp,PFMessOctaveNumber"%d\n",&pf->octaveNumber)); PFFSCANF((fp,PFMessVoiceNumber"%d\n",&pf->voiceNumber)); PFFSCANF((fp,PFMessIndexMax"%d\n",&pf->indexMax)); PFFSCANF((fp,PFMessSignalSize"%d\n",&pf->signalSize)); PFFSCANF((fp,PFMessSignalNumber"%d\n",&pf->signalNumber)); PFFSCANF((fp,PFMessDimension"%d\n",&pf->dimension)); PFFSCANF((fp,PFMessQNumber"%d\n",&pf->qNumber)); /* We verify that the values are meaningful */ if( _PFIsValid(pf) != PFYes ) return PFNotValid; /* We allocate space for the qs */ qArray = (double *) malloc(pf->qNumber*sizeof(double)); if( qArray == NULL ) return PFErrAlloc; /* We read the qs */ err = PFReadAsciiDoubleList(fp,PFMessQList,pf->qNumber,qArray); if( err != PFYes ) { free(qArray); return err; } /* We initialize the cell array */ pf->cellArray = PFCellArrayNew(pf->octaveNumber*pf->voiceNumber, pf->qNumber,qArray); if( pf->cellArray == NULL) { free(qArray); return PFErrAlloc; } /* We read the content of the cells */ for(nq=0;nq < pf->qNumber;nq++) if( PFCellReadAscii(fp,pf->cellArray[nq]) != PFYes ) { free(qArray); return PFErrFormat; } free(qArray); return PFYes;}/* Functions to convert Big Endian to Little Endian and Little to Big */static void PFBigLittleOneVar(void *var,size_t sizevar){ size_t i; unsigned char c; unsigned char *pvar; pvar = (unsigned char *) var; for(i=0;i<sizevar/2;i++) { c = *(pvar+i); *(pvar+i) = *(pvar+sizevar-1-i); *(pvar+sizevar-1-i) = c; }}static void PFBigLittleHeader(PartitionFunction pf){ PFBigLittleOneVar(&(pf->aMin),sizeof(double)); PFBigLittleOneVar(&(pf->octaveNumber),sizeof(int)); PFBigLittleOneVar(&(pf->voiceNumber),sizeof(int)); PFBigLittleOneVar(&(pf->indexMax),sizeof(int)); PFBigLittleOneVar(&(pf->signalSize),sizeof(int)); PFBigLittleOneVar(&(pf->signalNumber),sizeof(int)); PFBigLittleOneVar(&(pf->dimension),sizeof(int)); PFBigLittleOneVar(&(pf->qNumber),sizeof(int));}static void PFCellBigLittle(PartitionFunctionCell pfc){ int i; PFBigLittleOneVar(&(pfc->q),sizeof(double)); for(i=0;i< 7*pfc->size;i++) PFBigLittleOneVar(&(pfc->sTq[i]),sizeof(double));}/* ******************* */static int PFReadBinHeader(FILE *fp,PartitionFunction pf,int flagSwap){ PFFREAD( ((void *)pf, sizeof(struct PartitionFunction)-sizeof(PartitionFunctionCell *), 1,fp),1); if(flagSwap == PFYes) PFBigLittleHeader(pf); return PFYes;}static int PFCellReadBin(FILE *fp,PartitionFunctionCell pfc,int flagSwap){ int size; assert( fp != NULL && pfc != NULL ); assert( pfc->sTq != NULL ); assert( pfc->size > 0 ); PFFREAD( ((void *) &(pfc->q),sizeof(double),1,fp),1); PFFREAD( ((void *) &size,sizeof(int),1,fp),1); if (flagSwap == PFYes) PFBigLittleOneVar((void *) &size,sizeof(int)); if(pfc->size != size) return PFErrFormat; PFFREAD( ((void *) pfc->sTq,sizeof(double),7*pfc->size,fp),7*pfc->size); if (flagSwap == PFYes) PFCellBigLittle(pfc); return PFYes;}static int PFReadBin(FILE *fp,PartitionFunction pf){ char endianLine[PFMESSMAXSIZE+2]; int flagLittle,flagSwap; int nq; double *qArray; assert( fp != NULL && pf != NULL ); if( fgets(endianLine,PFMESSMAXSIZE+2,fp) == NULL) return PFReadErr; /* The last character in endianLine is \n we convert it to \0 */ endianLine[strlen(endianLine)-1] = '\0'; if( strcmp(endianLine,PFMessLittleEndian) == 0 ) flagLittle = PFYes; else if( strcmp(endianLine,PFMessBigEndian) == 0) flagLittle = PFNo; else return PFErrFormat; /* Is the endian convention in the file read the same as the computer we are working on? */ if( flagLittle != PFIsLittleEndian() )
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?