pf_lib.c

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

C
1,800
字号
{  int nq;  PartitionFunctionCell *cellArray;  if( pf == NULL ) return PFNo;  if( (qNumber < 0) || (pf->octaveNumber <= 0) || (pf->voiceNumber <= 0)      || ((qNumber == 0)&&(qArray != NULL)) )    return PFNotValid;  if( qNumber == 0 )    {      if(pf->cellArray != NULL)	{	  PFCellArrayDelete(pf->cellArray,pf->qNumber);	  pf->cellArray = NULL;	}      pf->qNumber = 0;    }  else    {      /* We want the qs to be sorted in increasing order */      qsort((void *)qArray,qNumber,sizeof(double),	    (int (*) (const void *, const void *) ) PFCompDouble);       /* each value can appear only once */      for(nq=0;nq < qNumber-1;nq++)	if(qArray[nq] >= qArray[nq+1])	  return PFNotValid;        cellArray = PFCellArrayNew(pf->octaveNumber*pf->voiceNumber,qNumber,				 qArray);      if( cellArray == NULL) 	return PFErrAlloc;        if(pf->cellArray != NULL)	PFCellArrayDelete(pf->cellArray,pf->qNumber);      pf->cellArray = cellArray;      pf->qNumber = qNumber;    }    pf->indexMax = -1;  return PFYes;}/************************************************* * * functions to read one field of a PartitionFunction * *************************************************//* method must be able to contain at least PFMETHODSIZE+1 char */void PFGetMethod(const PartitionFunction pf,char *method){  strcpy(method,pf->method);}double PFGetAMin(const PartitionFunction pf){  return pf->aMin;}int PFGetOctaveNumber(const PartitionFunction pf){  return pf->octaveNumber;}int PFGetVoiceNumber(const PartitionFunction pf){  return pf->voiceNumber;}int PFGetIndexMax(const PartitionFunction pf){  return pf->indexMax;}int PFGetSignalSize(const PartitionFunction pf){  return pf->signalSize;}int PFGetSignalNumber(const PartitionFunction pf){  return pf->signalNumber;}int PFGetDimension(const PartitionFunction pf){  return pf->dimension;}int PFGetQNumber(const PartitionFunction pf){  return pf->qNumber;}/* One is supposed to have check qNumber before using thess functions    so that enough space is available in qArray */void PFGetQList(const PartitionFunction pf,double *qArray){  int nq;    for(nq=0;nq < pf->qNumber;nq++)    qArray[nq] = pf->cellArray[nq]->q;}void PFGetQListFLOAT(const PartitionFunction pf,LWFLOAT *qArray){  int nq;    for(nq=0;nq < pf->qNumber;nq++)    qArray[nq] = (LWFLOAT) pf->cellArray[nq]->q;}/* One is supposed to have check qNumber before using thess functions    so that indexQ is in [0,qNumber[ */double PFGetQ(const PartitionFunction pf,int indexQ){  if(indexQ < 0)    return(-DBL_MAX);    if(indexQ >= pf->qNumber)    return(DBL_MAX);  return( pf->cellArray[indexQ]->q);}LWFLOAT PFGetQFLOAT(const PartitionFunction pf,int indexQ){  if(indexQ < 0)    return(-FLOAT_MAX);    if(indexQ >= pf->qNumber)    return(FLOAT_MAX);  return( (LWFLOAT) pf->cellArray[indexQ]->q);}/************************************************* * * functions to access computed partition functions * *************************************************//* It returns the size of the sTq sTqLogT... arrays    Very useful before calling PFAccesSig TQ | HQ | DQ.   It returns 0 the list of q's is empty or -1 if pf is not valid */ int PFAccessSize(const PartitionFunction pf){  if(PFIsValid(pf) != PFYes)    return -1;  if(pf->qNumber == 0)    return 0;    return pf->octaveNumber*pf->voiceNumber;}/* return the index of a q in the qList of pf    reurn -1 on failure */int PFAccessIndQ(const PartitionFunction pf,double q){  int nq;  if( PFIsValid(pf) != PFYes )    return -1;  if(pf->qNumber == 0)    return -1;    for(nq=0;nq < pf->qNumber;nq++)    if(fabs(pf->cellArray[nq]->q - q) <= PFQDIFFMAX)      return nq;    return -1;}/* Sets the LWFLOAT array to Tau(q).   Returns PFYes on success.   Mode is either PFEXTENSIVE or PFINTENSIVE.   tq must be able to contain the result (the size returned by PFAccessSize)   */int PFAccessTQFLOAT(const PartitionFunction pf,int indexQ,int mode,LWFLOAT *tq){  int i;  int size;  PartitionFunctionCell pfc;  if(pf == NULL) return PFNo;  if( (PFIsValid(pf) != PFYes) || (pf->qNumber == 0)      || (pf->qNumber <= indexQ) || (indexQ < 0) )     return PFNotValid;    pfc = pf->cellArray[indexQ];  size = pfc->size;  if( mode == PFEXTENSIVE )    {      for(i=0;i < size;i++)	{	  if(pfc->sTq[i] == 0)	    tq[i] = 0.0;	  else	    tq[i] = (LWFLOAT) log(pfc->sTq[i]);	}    }  else if( mode == PFINTENSIVE )    {      for(i=0;i <= pf->indexMax;i++)	tq[i] = (LWFLOAT) ( pfc->logSTq[i]/(double) pf->signalNumber );      for(;i < size;i++)	tq[i] = 0.0;    }  else return PFNotValid;  return PFYes;}/* Sets the LWFLOAT array to var[Tau(q)].   Returns PFYes on success.   vartq must be able to contain the result (the size returned by PFAccessSize)   */int PFAccessVarTQFLOAT(const PartitionFunction pf,int indexQ,LWFLOAT *vartq){  int i;  int size;  double signalNumber;  PartitionFunctionCell pfc;  if(pf == NULL) return PFNo;  if( (PFIsValid(pf) != PFYes) || (pf->qNumber == 0)       || (pf->qNumber <= indexQ) || (indexQ < 0) || (pf->signalNumber < 2) )     return PFNotValid;    pfc = pf->cellArray[indexQ];  size = pfc->size;  signalNumber = (double) pf->signalNumber;  for(i=0;i < size;i++)    {      for(i=0;i <= pf->indexMax;i++)	vartq[i] = (LWFLOAT) ( (pfc->log2STq[i] - pfc->logSTq[i]*pfc->logSTq[i]/signalNumber)/(signalNumber - 1.0) );      for(;i < size;i++)	vartq[i] = 0.0;    }    return PFYes;}/* Sets the LWFLOAT array to H(q).   Returns PFYes on success.   Mode is either PFEXTENSIVE or PFINTENSIVE.   hq must be able to contain the result (the size returned by PFAccessSize)   */int PFAccessHQFLOAT(const PartitionFunction pf,int indexQ,int mode,LWFLOAT *hq){  int i;  int size;  PartitionFunctionCell pfc;  if(pf == NULL) return PFNo;  if( (PFIsValid(pf) != PFYes) || (pf->qNumber == 0)      || (pf->qNumber <= indexQ) || (indexQ < 0) )     return PFNotValid;    pfc = pf->cellArray[indexQ];  size = pfc->size;  if( mode == PFEXTENSIVE )    {      for(i=0;i < size;i++)	{	  if(pfc->sTq[i] == 0)	    hq[i] = 0.0;	  else	    hq[i] = (LWFLOAT) ( pfc->sTqLogT[i] / pfc->sTq[i]);	}    }  else if( mode == PFINTENSIVE )    {      for(i=0;i <= pf->indexMax;i++)	hq[i] = (LWFLOAT) (pfc->sTqLogT_sTq[i] / (double) pf->signalNumber);      for(;i < size;i++)	hq[i] = 0.0;    }  else return PFNotValid;  return PFYes;}/* Sets the LWFLOAT array to var[H(q)].   Returns PFYes on success.   varhq must be able to contain the result (the size returned by PFAccessSize)   */int PFAccessVarHQFLOAT(const PartitionFunction pf,int indexQ,LWFLOAT *varhq){  int i;  int size;  double signalNumber;  PartitionFunctionCell pfc;  if(pf == NULL) return PFNo;  if( (PFIsValid(pf) != PFYes) || (pf->qNumber == 0)       || (pf->qNumber <= indexQ) || (indexQ < 0) || (pf->signalNumber < 2) )     return PFNotValid;    pfc = pf->cellArray[indexQ];  size = pfc->size;  signalNumber = (double) pf->signalNumber;  for(i=0;i < size;i++)    {      for(i=0;i <= pf->indexMax;i++)	varhq[i] = (LWFLOAT) ( (pfc->sTqLogT_sTq2[i] - pfc->sTqLogT_sTq[i]*pfc->sTqLogT_sTq[i]/signalNumber)/(signalNumber - 1.0) );      for(;i < size;i++)	varhq[i] = 0.0;    }    return PFYes;}/* Sets the LWFLOAT array to D(q).   Returns PFYes on success.   Mode is either PFEXTENSIVE or PFINTENSIVE.   dq must be able to contain the result (the size returned by PFAccessSize) */int PFAccessDQFLOAT(const PartitionFunction pf,int indexQ,int mode,LWFLOAT *dq){  int i;  int size;  PartitionFunctionCell pfc;  if(pf == NULL) return PFNo;  if( (PFIsValid(pf) != PFYes) || (pf->qNumber == 0)      || (pf->qNumber <= indexQ) || (indexQ < 0) )     return PFNotValid;    pfc = pf->cellArray[indexQ];  size = pfc->size;  if( mode == PFEXTENSIVE )    {      for(i=0;i < size;i++)	{	  if(pfc->sTq[i] == 0)	    dq[i] = 0.0;	  else	    dq[i] = (LWFLOAT) ( pfc->q*pfc->sTqLogT[i]/pfc->sTq[i] - log(pfc->sTq[i]) );	}    }  else if( mode == PFINTENSIVE )    {      for(i=0;i <= pf->indexMax;i++)	dq[i] = (LWFLOAT) ( (pfc->q*pfc->sTqLogT_sTq[i] - pfc->logSTq[i])/(double) pf->signalNumber );      for(;i < size;i++)	dq[i] = 0.0;    }  else return PFNotValid;  return PFYes;}/* Sets the LWFLOAT array to var[D(q)].   Returns PFYes on success.   vardq must be able to contain the result (the size returned by PFAccessSize)   */int PFAccessVarDQFLOAT(const PartitionFunction pf,int indexQ,LWFLOAT *vardq){  int i;  int size;  double signalNumber;  double q;  PartitionFunctionCell pfc;  if(pf == NULL) return PFNo;  if( (PFIsValid(pf) != PFYes) || (pf->qNumber == 0)       || (pf->qNumber <= indexQ) || (indexQ < 0) || (pf->signalNumber < 2) )     return PFNotValid;    pfc = pf->cellArray[indexQ];  size = pfc->size;  signalNumber = (double) pf->signalNumber;  q = pfc->q;  for(i=0;i < size;i++)    {      for(i=0;i <= pf->indexMax;i++)	vardq[i] = (LWFLOAT) ( (q*q*pfc->sTqLogT_sTq2[i] - 2*q*pfc->logSTqSTqLogT_sTq[i] + pfc->log2STq[i] - (q*pfc->sTqLogT_sTq[i] - pfc->logSTq[i])/signalNumber)/(signalNumber - 1.0) );      for(;i < size;i++)	vardq[i] = 0.0;    }    return PFYes;}/************************************************* * * Initialisation of PartitionFunction * *************************************************//* It initialiszes pf for the computation of a new partition function.   The arguments must be meaningful.   Returns PFYes if it succeeds. */int PFInit(PartitionFunction pf,char *method,double aMin,	   int octaveNumber,int voiceNumber,int signalSize,int dimension,	   int qNumber,double *qArray){  /* Some verifications */  if( (pf == NULL) || (method == NULL) )    return PFNo;  if(PFSetMethod(pf,method) != PFYes)    return PFNotValid;  if(PFSetAMin(pf,aMin ) != PFYes)    return PFNotValid;  if(PFSetOctaveNumber(pf,octaveNumber) != PFYes)    return PFNotValid;  if(PFSetVoiceNumber(pf,voiceNumber) != PFYes)    return PFNotValid;  pf->indexMax = -1;  if(PFSetSignalSize(pf,signalSize) != PFYes)    return PFNotValid;  pf->signalNumber = 1;  if(PFSetDimension(pf,dimension) != PFYes)    return PFNotValid;  if(PFSetQList(pf,qNumber,qArray) != PFYes)    return PFNotValid;  return PFYes;}/* Returns PFYes if pf is valid (meaningful content).   But does not check the cellArray */static int _PFIsValid(PartitionFunction pf){  if(pf == NULL) return PFNo;    if( (strlen(pf->method) > PFMETHODSIZE) || (pf->aMin <= 0)      || (pf->octaveNumber <= 0) || (pf->voiceNumber <= 0 )      || (pf->indexMax < -1)       || (pf->indexMax >= pf->voiceNumber*pf->octaveNumber)       || (pf->signalSize <= 0) || (pf->signalNumber <= 0)       || (pf->dimension <= 0) || (pf->qNumber < 0) )    return PFNotValid;  return PFYes;}static int _PFCellArrayIsValid(PartitionFunctionCell *cellArray,int qNumber,			       int size){  int nq;  if( cellArray == NULL ) return PFNotValid;  for(nq=0;nq < qNumber;nq++)    if(cellArray[nq]->size != size)      return PFNotValid;    /* The q have to be sorted in increasing order and each value     can appear only once */

⌨️ 快捷键说明

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