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 + -
显示快捷键?