pf_lib.c

来自「LastWave」· C语言 代码 · 共 1,800 行 · 第 1/4 页

C
1,800
字号
/*..........................................................................*//*                                                                          *//*      PARTITION FUNCTION 3.2                                              *//*                                                                          *//*      Copyright (C) 1998-2005 Benjamin Audit.                             *//*      email : Benjamin.Audit@ens-lyon.fr                                  *//*                                                                          *//*..........................................................................*//*                                                                          *//*      This program is a free software, you can redistribute it and/or     *//*      modify it under the terms of the GNU General Public License as      *//*      published by the Free Software Foundation; either version 2 of the  *//*      License, or (at your option) any later version                      *//*                                                                          *//*      This program is distributed in the hope that it will be useful,     *//*      but WITHOUT ANY WARRANTY; without even the implied warranty of      *//*      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the       *//*      GNU General Public License for more details.                        *//*                                                                          *//*      You should have received a copy of the GNU General Public License   *//*      along with this program (in a file named COPYRIGHT);                *//*      if not, write to the Free Software Foundation, Inc.,                *//*      59 Temple Place, Suite 330, Boston, MA  02111-1307  USA             *//*                                                                          *//*..........................................................................*/#include "pf_lib.h"#include <stdlib.h>#include <string.h>#include <math.h>#include <float.h>#include <assert.h>#ifndef NOT_USED_WITH_LWextern void *Malloc(size_t size);extern void *Calloc(int n, size_t size);extern void Free(void * ptr);#define malloc Malloc#define calloc Calloc#define free Free#endif /* NOT_USED_WITH_LW */typedef struct PartitionFunctionCell{  double q;  int size;  double *sTq;  double *sTqLogT;  double *logSTq;  double *sTqLogT_sTq;  double *log2STq;  double *sTqLogT_sTq2;  double *logSTqSTqLogT_sTq;} *PartitionFunctionCell;struct PartitionFunction{  /* + 1 for the terminating null byte */  char method[PFMETHODSIZE+1];  double aMin;  int octaveNumber;  int voiceNumber;  int indexMax;  int signalSize;  int signalNumber;  int dimension;  int qNumber;  PartitionFunctionCell *cellArray;};/************************************************* * * Stupid functions to compare double and used by qsort * *************************************************/static int PFCompDouble(const double *d1,const double *d2){  if(*d1<*d2)    return -1;  else if(*d1 == *d2)    return 0;  else    return +1;}static int PFCellCompQ(const PartitionFunctionCell *pfc1,const PartitionFunctionCell *pfc2){  return PFCompDouble(&(*pfc1)->q,&(*pfc2)->q);}/************************************************* * * DesAllocation of PartitionFunction(Cell)(Array) * *************************************************/static void PFCellDelete(PartitionFunctionCell pfc){  if( pfc == NULL ) return;  /* We only use one memory allocation for the 7 arrays */  free(pfc->sTq);  free(pfc);}static void PFCellArrayDelete(PartitionFunctionCell *cellArray,int qNumber){ int nq; if( cellArray == NULL ) return; assert(qNumber > 0); for(nq = 0; nq < qNumber; nq++)   PFCellDelete(cellArray[nq]);  free(cellArray);}void PFDelete(PartitionFunction pf){  if( pf == NULL ) return;  PFCellArrayDelete(pf->cellArray,pf->qNumber);  free(pf);}/************************************************* * * Allocation of PartitionFunction(Cell)(Array) * *************************************************//* Returns an initialized cell (using q and size) in which the space    for the double *s is allocated and initialised to 0    Returns NULL if it fails or if size <= 0 */static PartitionFunctionCell PFCellNew(double q,int size){  PartitionFunctionCell pfc;  if( size <= 0 ) return NULL;  pfc = (PartitionFunctionCell) malloc(sizeof(struct PartitionFunctionCell));  if( pfc == NULL ) return NULL;    /* We use one memory allocation for the 7 arrays */  pfc->sTq = (double*) calloc(7*size,sizeof(double));  if( pfc->sTq == NULL )     {      free(pfc);      return NULL;    }  pfc->sTqLogT = pfc->sTq + size;  pfc->logSTq = pfc->sTq + 2*size;  pfc->sTqLogT_sTq = pfc->sTq + 3*size;  pfc->log2STq = pfc->sTq + 4*size;  pfc->sTqLogT_sTq2 = pfc->sTq + 5*size;  pfc->logSTqSTqLogT_sTq = pfc->sTq + 6*size;  pfc->q = q;  pfc->size = size;  return pfc;}/* Returns a pointer to a new PartitionFunctionCell, copy of pfc    or NULL if it fails */static PartitionFunctionCell PFCellCopy(const PartitionFunctionCell pfc){  PartitionFunctionCell pfcNew;    if(pfc == NULL) return NULL;    pfcNew = PFCellNew(pfc->q,pfc->size);  if(pfcNew == NULL) return NULL;    /* This is correct because we use only one memory allocation for the 7 arrays   */  memcpy(pfcNew->sTq,pfc->sTq,7*pfc->size*sizeof(double));  return pfcNew;}/* It returns a PartitionFunctionCell * pointing to qNumber initialized    cells (using size and qArray) in which the space for the double *s    is allocated and initialised to 0 */static PartitionFunctionCell *PFCellArrayNew(int size,int qNumber,					     double *qArray){  int nq;  PartitionFunctionCell *cellArray;  assert( size > 0  && qNumber > 0 );    cellArray = (PartitionFunctionCell *)     malloc(qNumber*sizeof(PartitionFunctionCell));  if( cellArray == NULL ) return NULL;    for(nq = 0; nq < qNumber; nq++)    {      cellArray[nq] = PFCellNew(qArray[nq],size);            /* If we can't allocate one cell, we delete the one already allocated */      /* and we return NULL */      if( cellArray[nq] == NULL )	{	  for(nq--; nq >= 0; nq--)	    PFCellDelete(cellArray[nq]);	  free(cellArray);	  return NULL;	}    }  return cellArray;}static PartitionFunctionCell *PFCellArrayConcat(int qNumber1,const PartitionFunctionCell *cellArray1,int qNumber2,const PartitionFunctionCell *cellArray2){  int nq;  PartitionFunctionCell *cellArrayNew;    cellArrayNew = (PartitionFunctionCell *)     malloc((qNumber1+qNumber2)*sizeof(PartitionFunctionCell));  if(cellArrayNew == NULL) return NULL;  for(nq=0;nq < qNumber1+qNumber2;nq++)    {      cellArrayNew[nq] = PFCellCopy( (nq < qNumber1) ? cellArray1[nq] : cellArray2[nq - qNumber1]);      if(cellArrayNew[nq] == NULL)	for(nq--;nq >= 0;nq--)	  {	    PFCellDelete(cellArrayNew[nq]);	    free(cellArrayNew);	    return NULL;	  }    }  /* Now we have to sort */  qsort((void *)cellArrayNew,qNumber1+qNumber2,sizeof(PartitionFunctionCell),	(int (*) (const void *, const void *) ) &PFCellCompQ);  return cellArrayNew;}/* Returns a pointer to a new PartitionFunctionCell *, copy of cellArray    or NULL if it fails */static PartitionFunctionCell *PFCellArrayCopy(const PartitionFunctionCell *cellArray,int qNumber){  int nq;  PartitionFunctionCell *cellArrayNew;  if( (cellArray == NULL) || (qNumber <= 0) ) return NULL;  cellArrayNew = (PartitionFunctionCell *)     malloc(qNumber*sizeof(PartitionFunctionCell));  if( cellArray == NULL )     return NULL;  for(nq=0;nq < qNumber;nq++)    {      cellArrayNew[nq] = PFCellCopy(cellArray[nq]);      if(cellArrayNew[nq] == NULL)	{	  for(nq--;nq >= 0;nq--)	    PFCellDelete(cellArrayNew[nq]);	  free(cellArrayNew);	  return NULL;	}    }    return cellArrayNew;}/* Returns a new PartitionFunction initialized with non sense fields.   Returns NULL if it fails. */PartitionFunction PFNew(void){  PartitionFunction pf;    pf = (PartitionFunction) malloc(sizeof(struct PartitionFunction));  if( pf == NULL ) return NULL;    pf->method[0] = '\0';  pf->aMin = -1.0;  pf->octaveNumber = -1;  pf->voiceNumber = -1;  pf->indexMax = -2;  pf->signalSize = -1;  pf->signalNumber = -1;  pf->dimension = -1;  pf->qNumber = 0;  pf->cellArray = NULL;  return pf;}/* Returns a pointer to a new PartitionFunction, copy of pf    or NULL if it fails */PartitionFunction PFCopy(const PartitionFunction pf){  PartitionFunction pfNew;  PartitionFunctionCell *cellArray;  if(pf == NULL) return NULL;  if( PFIsValid(pf) != PFYes )    return NULL;  if(pf->qNumber != 0)    {      cellArray = PFCellArrayCopy(pf->cellArray,pf->qNumber);      if(cellArray == NULL)	return NULL;    }  else cellArray = NULL;  pfNew = PFNew();  if(pfNew == NULL)    {      PFCellArrayDelete(cellArray,pf->qNumber);      return NULL;    }  strcpy(pfNew->method,pf->method);  pfNew->aMin = pf->aMin;  pfNew->octaveNumber = pf->octaveNumber;  pfNew->voiceNumber = pf->voiceNumber;  pfNew->indexMax = pf->indexMax;  pfNew->signalSize = pf->signalSize;  pfNew->signalNumber = pf->signalNumber;  pfNew->dimension = pf->dimension;  pfNew->qNumber = pf->qNumber;  pfNew->cellArray = cellArray;  return pfNew;}/* Set all the arrays to 0 */static void PFCReset(PartitionFunctionCell pfc){  int i;    for(i=0;i<pfc->size;i++)    {            pfc->sTq[i] = 0.;      pfc->sTqLogT[i] = 0.;      pfc->logSTq[i] = 0.;      pfc->sTqLogT_sTq[i] = 0.;      pfc->log2STq[i] = 0.;      pfc->sTqLogT_sTq2[i] = 0.;      pfc->logSTqSTqLogT_sTq[i] = 0.;    }}int PFReset(PartitionFunction pf){  int nq;  if(pf == NULL) return PFNo;  if( PFIsValid(pf) != PFYes )    return PFNo;    for(nq=0;nq < pf->qNumber;nq++)    PFCReset(pf->cellArray[nq]);  pf->indexMax = -1;  pf->signalNumber = 1;  return PFYes;}/************************************************* * * functions to modify one field of a PartitionFunction * *************************************************/int PFSetMethod(PartitionFunction pf,const char *method){  if( pf == NULL ) return PFNo;  if( method == NULL ) return PFNo;  if( strlen(method) > PFMETHODSIZE)    return PFNotValid;  strcpy(pf->method,method);  return PFYes;}int PFSetAMin(PartitionFunction pf,double aMin){  if( pf == NULL ) return PFNo;  if( aMin <= 0 ) return PFNotValid;  pf->aMin = aMin;    return PFYes;}static int PFSetOctaveNumber(PartitionFunction pf,int octaveNumber){  if( pf == NULL ) return PFNo;  if( octaveNumber <= 0) return PFNotValid;  pf->octaveNumber = octaveNumber;    return PFYes;}static int PFSetVoiceNumber(PartitionFunction pf,int voiceNumber){  if( pf == NULL ) return PFNo;  if( voiceNumber <= 0) return PFNotValid;  pf->voiceNumber = voiceNumber;    return PFYes;} int PFSetSignalSize(PartitionFunction pf,int signalSize){  if( pf == NULL ) return PFNo;  if( signalSize <= 0) return PFNotValid;  pf->signalSize = signalSize;    return PFYes;}int PFSetDimension(PartitionFunction pf,int dimension){  if( pf == NULL ) return PFNo;  if( dimension <= 0) return PFNotValid;  pf->dimension = dimension;    return PFYes;}int PFSetQList(PartitionFunction pf,int qNumber,double *qArray)

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?